[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.346 and 1.374

version 1.346, 2019/09/03 20:51:49 version 1.374, 2019/12/10 22:37:20
Line 16 
Line 16 
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/stat.h>  #include <sys/stat.h>
   
   #ifdef WITH_OPENSSL
 #include <openssl/evp.h>  #include <openssl/evp.h>
 #include <openssl/pem.h>  #include <openssl/pem.h>
   #endif
   
   #include <stdint.h>
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <netdb.h>  #include <netdb.h>
Line 26 
Line 29 
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <stdarg.h>
 #include <unistd.h>  #include <unistd.h>
 #include <limits.h>  #include <limits.h>
 #include <locale.h>  #include <locale.h>
Line 49 
Line 53 
 #include "utf8.h"  #include "utf8.h"
 #include "authfd.h"  #include "authfd.h"
 #include "sshsig.h"  #include "sshsig.h"
   #include "ssh-sk.h"
   #include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
   
 #ifdef ENABLE_PKCS11  #ifdef ENABLE_PKCS11
 #include "ssh-pkcs11.h"  #include "ssh-pkcs11.h"
Line 85 
Line 91 
 static int fingerprint_hash = SSH_FP_HASH_DEFAULT;  static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
   
 /* The identity file name, given on the command line or entered by the user. */  /* The identity file name, given on the command line or entered by the user. */
 static char identity_file[1024];  static char identity_file[PATH_MAX];
 static int have_identity = 0;  static int have_identity = 0;
   
 /* This is set to the passphrase if given on the command line. */  /* This is set to the passphrase if given on the command line. */
Line 108 
Line 114 
 static u_int64_t cert_valid_to = ~0ULL;  static u_int64_t cert_valid_to = ~0ULL;
   
 /* Certificate options */  /* Certificate options */
 #define CERTOPT_X_FWD   (1)  #define CERTOPT_X_FWD                           (1)
 #define CERTOPT_AGENT_FWD       (1<<1)  #define CERTOPT_AGENT_FWD                       (1<<1)
 #define CERTOPT_PORT_FWD        (1<<2)  #define CERTOPT_PORT_FWD                        (1<<2)
 #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_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 140 
Line 147 
 /* Load key from this PKCS#11 provider */  /* Load key from this PKCS#11 provider */
 static char *pkcs11provider = NULL;  static char *pkcs11provider = NULL;
   
   /* FIDO/U2F provider to use */
   static char *sk_provider = NULL;
   
 /* Format for writing private keys */  /* Format for writing private keys */
 static int private_key_format = SSHKEY_PRIVATE_OPENSSH;  static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
   
Line 254 
Line 264 
                 case KEY_ECDSA:                  case KEY_ECDSA:
                         name = _PATH_SSH_CLIENT_ID_ECDSA;                          name = _PATH_SSH_CLIENT_ID_ECDSA;
                         break;                          break;
                   case KEY_ECDSA_SK_CERT:
                   case KEY_ECDSA_SK:
                           name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
                           break;
                 case KEY_RSA_CERT:                  case KEY_RSA_CERT:
                 case KEY_RSA:                  case KEY_RSA:
                         name = _PATH_SSH_CLIENT_ID_RSA;                          name = _PATH_SSH_CLIENT_ID_RSA;
Line 262 
Line 276 
                 case KEY_ED25519_CERT:                  case KEY_ED25519_CERT:
                         name = _PATH_SSH_CLIENT_ID_ED25519;                          name = _PATH_SSH_CLIENT_ID_ED25519;
                         break;                          break;
                   case KEY_ED25519_SK:
                   case KEY_ED25519_SK_CERT:
                           name = _PATH_SSH_CLIENT_ID_ED25519_SK;
                           break;
                 case KEY_XMSS:                  case KEY_XMSS:
                 case KEY_XMSS_CERT:                  case KEY_XMSS_CERT:
                         name = _PATH_SSH_CLIENT_ID_XMSS;                          name = _PATH_SSH_CLIENT_ID_XMSS;
Line 550 
Line 568 
                 error("%s: remaining bytes in key blob %d", __func__, rlen);                  error("%s: remaining bytes in key blob %d", __func__, rlen);
   
         /* try the key */          /* try the key */
         if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 ||          if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
             sshkey_verify(key, sig, slen, data, sizeof(data), NULL, 0) != 0) {              NULL, NULL, 0) != 0 ||
               sshkey_verify(key, sig, slen, data, sizeof(data),
               NULL, 0, NULL) != 0) {
                 sshkey_free(key);                  sshkey_free(key);
                 free(sig);                  free(sig);
                 return NULL;                  return NULL;
Line 633 
Line 653 
                 *k = do_convert_private_ssh2(buf);                  *k = do_convert_private_ssh2(buf);
         else if ((r = sshkey_fromb(buf, k)) != 0)          else if ((r = sshkey_fromb(buf, k)) != 0)
                 fatal("decode blob failed: %s", ssh_err(r));                  fatal("decode blob failed: %s", ssh_err(r));
           sshbuf_free(buf);
         fclose(fp);          fclose(fp);
 }  }
   
Line 1626 
Line 1647 
             (certflags_flags & CERTOPT_USER_RC) != 0)              (certflags_flags & CERTOPT_USER_RC) != 0)
                 add_flag_option(c, "permit-user-rc");                  add_flag_option(c, "permit-user-rc");
         if ((which & OPTIONS_CRITICAL) != 0 &&          if ((which & OPTIONS_CRITICAL) != 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)              certflags_src_addr != NULL)
                 add_string_option(c, "source-address", certflags_src_addr);                  add_string_option(c, "source-address", certflags_src_addr);
         for (i = 0; i < ncert_userext; i++) {          for (i = 0; i < ncert_userext; i++) {
Line 1675 
Line 1699 
 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, u_int compat, void *ctx)      const char *alg, const char *provider, u_int compat, void *ctx)
 {  {
         int *agent_fdp = (int *)ctx;          int *agent_fdp = (int *)ctx;
   
Line 1691 
Line 1715 
         int r, i, fd, found, agent_fd = -1;          int r, i, fd, found, agent_fd = -1;
         u_int n;          u_int n;
         struct sshkey *ca, *public;          struct sshkey *ca, *public;
         char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;          char valid[64], *otmp, *tmp, *cp, *out, *comment;
           char *ca_fp = NULL, **plist = NULL;
         FILE *f;          FILE *f;
         struct ssh_identitylist *agent_ids;          struct ssh_identitylist *agent_ids;
         size_t j;          size_t j;
           struct notifier_ctx *notifier = NULL;
   
 #ifdef ENABLE_PKCS11  #ifdef ENABLE_PKCS11
         pkcs11_init(1);          pkcs11_init(1);
Line 1740 
Line 1766 
                 fatal("CA key type %s doesn't match specified %s",                  fatal("CA key type %s doesn't match specified %s",
                     sshkey_ssh_name(ca), key_type_name);                      sshkey_ssh_name(ca), key_type_name);
         }          }
           ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
   
         for (i = 0; i < argc; i++) {          for (i = 0; i < argc; i++) {
                 /* Split list of principals */                  /* Split list of principals */
Line 1761 
Line 1788 
                 if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)                  if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
                         fatal("%s: unable to open \"%s\": %s",                          fatal("%s: unable to open \"%s\": %s",
                             __func__, tmp, ssh_err(r));                              __func__, tmp, ssh_err(r));
                 if (public->type != KEY_RSA && public->type != KEY_DSA &&                  if (sshkey_is_cert(public))
                     public->type != KEY_ECDSA && public->type != KEY_ED25519 &&  
                     public->type != KEY_XMSS)  
                         fatal("%s: key \"%s\" type %s cannot be certified",                          fatal("%s: key \"%s\" type %s cannot be certified",
                             __func__, tmp, sshkey_type(public));                              __func__, tmp, sshkey_type(public));
   
Line 1787 
Line 1812 
   
                 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, agent_signer, &agent_fd)) != 0)                              key_type_name, sk_provider, agent_signer,
                               &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));
                 } else {                  } else {
                         if ((sshkey_certify(public, ca, key_type_name)) != 0)                          if (sshkey_is_sk(ca) &&
                               (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
                                   notifier = notify_start(0,
                                       "Confirm user presence for key %s %s",
                                       sshkey_type(ca), ca_fp);
                           }
                           r = sshkey_certify(public, ca, key_type_name,
                               sk_provider);
                           notify_complete(notifier);
                           if (r != 0)
                                 fatal("Couldn't certify key %s: %s",                                  fatal("Couldn't certify key %s: %s",
                                     tmp, ssh_err(r));                                      tmp, ssh_err(r));
                 }                  }
Line 1829 
Line 1864 
                 if (cert_serial_autoinc)                  if (cert_serial_autoinc)
                         cert_serial++;                          cert_serial++;
         }          }
           free(ca_fp);
 #ifdef ENABLE_PKCS11  #ifdef ENABLE_PKCS11
         pkcs11_terminate();          pkcs11_terminate();
 #endif  #endif
Line 1927 
Line 1963 
                 certflags_flags &= ~CERTOPT_USER_RC;                  certflags_flags &= ~CERTOPT_USER_RC;
         else if (strcasecmp(opt, "permit-user-rc") == 0)          else if (strcasecmp(opt, "permit-user-rc") == 0)
                 certflags_flags |= CERTOPT_USER_RC;                  certflags_flags |= CERTOPT_USER_RC;
           else if (strcasecmp(opt, "touch-required") == 0)
                   certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
           else if (strcasecmp(opt, "no-touch-required") == 0)
                   certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
         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 1980 
Line 2020 
                     strcmp(name, "permit-agent-forwarding") == 0 ||                      strcmp(name, "permit-agent-forwarding") == 0 ||
                     strcmp(name, "permit-port-forwarding") == 0 ||                      strcmp(name, "permit-port-forwarding") == 0 ||
                     strcmp(name, "permit-pty") == 0 ||                      strcmp(name, "permit-pty") == 0 ||
                     strcmp(name, "permit-user-rc") == 0))                      strcmp(name, "permit-user-rc") == 0 ||
                       strcmp(name, "no-touch-required") == 0)) {
                         printf("\n");                          printf("\n");
                 else if (in_critical &&                  } else if (in_critical &&
                     (strcmp(name, "force-command") == 0 ||                      (strcmp(name, "force-command") == 0 ||
                     strcmp(name, "source-address") == 0)) {                      strcmp(name, "source-address") == 0)) {
                         if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)                          if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
Line 2466 
Line 2507 
 {  {
         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;          char *wfile = NULL, *asig = NULL, *fp = NULL;
         char *asig = NULL;  
   
         if (!quiet) {          if (!quiet) {
                 if (fd == STDIN_FILENO)                  if (fd == STDIN_FILENO)
Line 2475 
Line 2515 
                 else                  else
                         fprintf(stderr, "Signing file %s\n", filename);                          fprintf(stderr, "Signing file %s\n", filename);
         }          }
         if ((r = sshsig_sign_fd(signkey, NULL, fd, sig_namespace,          if (signer == NULL && sshkey_is_sk(signkey) &&
               (signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
                   if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
                       SSH_FP_DEFAULT)) == NULL)
                           fatal("%s: sshkey_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,
             &sigbuf, signer, signer_ctx)) != 0) {              &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 2611 
Line 2660 
         struct sshbuf *sigbuf = NULL, *abuf = NULL;          struct sshbuf *sigbuf = NULL, *abuf = NULL;
         struct sshkey *sign_key = NULL;          struct sshkey *sign_key = NULL;
         char *fp = NULL;          char *fp = NULL;
           struct sshkey_sig_details *sig_details = NULL;
   
           memset(&sig_details, 0, sizeof(sig_details));
         if ((abuf = sshbuf_new()) == NULL)          if ((abuf = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new() failed", __func__);                  fatal("%s: sshbuf_new() failed", __func__);
   
Line 2629 
Line 2680 
                 return r;                  return r;
         }          }
         if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,          if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
             &sign_key)) != 0)              &sign_key, &sig_details)) != 0)
                 goto done; /* sshsig_verify() prints error */                  goto done; /* sshsig_verify() prints error */
   
         if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,          if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
             SSH_FP_DEFAULT)) == NULL)              SSH_FP_DEFAULT)) == NULL)
                 fatal("%s: sshkey_fingerprint failed", __func__);                  fatal("%s: sshkey_fingerprint failed", __func__);
         debug("Valid (unverified) signature from key %s", fp);          debug("Valid (unverified) signature from key %s", fp);
           if (sig_details != NULL) {
                   debug2("%s: signature details: counter = %u, flags = 0x%02x",
                       __func__, sig_details->sk_counter, sig_details->sk_flags);
           }
         free(fp);          free(fp);
         fp = NULL;          fp = NULL;
   
Line 2646 
Line 2701 
                 }                  }
         }          }
   
         if ((r = sshsig_check_allowed_keys(allowed_keys, sign_key,          if (allowed_keys != NULL &&
             principal, sig_namespace)) != 0) {              (r = sshsig_check_allowed_keys(allowed_keys, sign_key,
                                              principal, sig_namespace)) != 0) {
                 debug3("sshsig_check_allowed_keys failed: %s", ssh_err(r));                  debug3("sshsig_check_allowed_keys failed: %s", ssh_err(r));
                 goto done;                  goto done;
         }          }
Line 2661 
Line 2717 
                                 fatal("%s: sshkey_fingerprint failed",                                  fatal("%s: sshkey_fingerprint failed",
                                     __func__);                                      __func__);
                         }                          }
                         printf("Good \"%s\" signature for %s with %s key %s\n",                          if (principal == NULL) {
                             sig_namespace, principal,                                  printf("Good \"%s\" signature with %s key %s\n",
                             sshkey_type(sign_key), fp);                                         sig_namespace, sshkey_type(sign_key), fp);
   
                           } else {
                                   printf("Good \"%s\" signature for %s with %s key %s\n",
                                          sig_namespace, principal,
                                          sshkey_type(sign_key), fp);
                           }
                 } else {                  } else {
                         printf("Could not verify signature.\n");                          printf("Could not verify signature.\n");
                 }                  }
Line 2673 
Line 2735 
         sshbuf_free(sigbuf);          sshbuf_free(sigbuf);
         sshbuf_free(abuf);          sshbuf_free(abuf);
         sshkey_free(sign_key);          sshkey_free(sign_key);
           sshkey_sig_details_free(sig_details);
         free(fp);          free(fp);
         return ret;          return ret;
 }  }
Line 2681 
Line 2744 
 usage(void)  usage(void)
 {  {
         fprintf(stderr,          fprintf(stderr,
             "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa] [-m format]\n"              "usage: ssh-keygen [-q] [-b bits] [-C comment] [-f output_keyfile] [-m format]\n"
             "                  [-N new_passphrase] [-C comment] [-f output_keyfile]\n"              "                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
             "       ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-m format]\n"              "                  [-N new_passphrase] [-w provider] [-x flags]\n"
             "                   [-f keyfile]\n"              "       ssh-keygen -p [-f keyfile] [-m format] [-N new_passphrase]\n"
             "       ssh-keygen -i [-m key_format] [-f input_keyfile]\n"              "                   [-P old_passphrase]\n"
             "       ssh-keygen -e [-m key_format] [-f input_keyfile]\n"              "       ssh-keygen -i [-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 [-P passphrase] [-C comment] [-f keyfile]\n"              "       ssh-keygen -c [-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 2696 
Line 2760 
             "       ssh-keygen -D pkcs11\n");              "       ssh-keygen -D pkcs11\n");
 #endif  #endif
         fprintf(stderr,          fprintf(stderr,
             "       ssh-keygen -F hostname [-f known_hosts_file] [-l]\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"
             "       ssh-keygen -r hostname [-f input_keyfile] [-g]\n"              "       ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
             "       ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n"              "       ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n"
             "       ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"              "       ssh-keygen -f input_file -T output_file [-v] [-a rounds] [-J num_lines]\n"
             "                  [-j start_line] [-K checkpt] [-W generator]\n"              "                  [-j start_line] [-K checkpt] [-W generator]\n"
 #endif  #endif
             "       ssh-keygen -s ca_key -I certificate_identity [-h] [-U]\n"              "       ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
             "                  [-D pkcs11_provider] [-n principals] [-O option]\n"              "                  [-n principals] [-O option] [-V validity_interval]\n"
             "                  [-V validity_interval] [-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\n"              "       ssh-keygen -A [-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 -f krl_file file ...\n"              "       ssh-keygen -Q -f krl_file file ...\n"
             "       ssh-keygen -Y sign -f sign_key -n namespace\n"              "       ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
             "       ssh-keygen -Y verify -I signer_identity -s signature_file\n"              "       ssh-keygen -Y sign -f key_file -n namespace file ...\n"
             "                  -n namespace -f allowed_keys [-r revoked_keys]\n");              "       ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
               "                   -n namespace -s signature_file [-r revocation_file]\n");
         exit(1);          exit(1);
 }  }
   
Line 2736 
Line 2801 
         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;
         unsigned long long cert_serial = 0;          unsigned long long ull, cert_serial = 0;
         char *identity_comment = NULL, *ca_key_path = NULL;          char *identity_comment = NULL, *ca_key_path = NULL;
         u_int32_t bits = 0;          u_int32_t bits = 0;
           uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
         FILE *f;          FILE *f;
         const char *errstr;          const char *errstr;
         int log_level = SYSLOG_LEVEL_INFO;          int log_level = SYSLOG_LEVEL_INFO;
Line 2758 
Line 2824 
         /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */          /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
         sanitise_stdfd();          sanitise_stdfd();
   
   #ifdef WITH_OPENSSL
         OpenSSL_add_all_algorithms();          OpenSSL_add_all_algorithms();
   #endif
         log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);          log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
   
         setlocale(LC_CTYPE, "");          setlocale(LC_CTYPE, "");
Line 2770 
Line 2838 
         if (gethostname(hostname, sizeof(hostname)) == -1)          if (gethostname(hostname, sizeof(hostname)) == -1)
                 fatal("gethostname: %s", strerror(errno));                  fatal("gethostname: %s", strerror(errno));
   
         /* Remaining characters: dw */          sk_provider = getenv("SSH_SK_PROVIDER");
         while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"  
           /* Remaining character: d */
           while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvy"
             "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:"              "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:"
             "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {              "a:b:f:g:j:m:n:r:s:t:w:x:z:")) != -1) {
                 switch (opt) {                  switch (opt) {
                 case 'A':                  case 'A':
                         gen_all_hostkeys = 1;                          gen_all_hostkeys = 1;
Line 2873 
Line 2943 
                         quiet = 1;                          quiet = 1;
                         break;                          break;
                 case 'e':                  case 'e':
                 case 'x':  
                         /* export key */                          /* export key */
                         convert_to = 1;                          convert_to = 1;
                         break;                          break;
Line 2931 
Line 3000 
                 case 'Y':                  case 'Y':
                         sign_op = optarg;                          sign_op = optarg;
                         break;                          break;
                   case 'w':
                           sk_provider = optarg;
                           break;
                   case 'x':
                           if (*optarg == '\0')
                                   fatal("Missing security key flags");
                           if (strcasecmp(optarg, "no-touch-required") == 0)
                                   sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
                           else {
                                   ull = strtoull(optarg, &ep, 0);
                                   if (*ep != '\0')
                                           fatal("Security key flags \"%s\" is "
                                               "not a number", optarg);
                                   if (ull > 0xff) {
                                           fatal("Invalid security key "
                                               "flags 0x%llx", ull);
                                   }
                                   sk_flags = (uint8_t)ull;
                           }
                           break;
                 case 'z':                  case 'z':
                         errno = 0;                          errno = 0;
                         if (*optarg == '+') {                          if (*optarg == '+') {
Line 2992 
Line 3081 
                 }                  }
         }          }
   
           if (sk_provider == NULL)
                   sk_provider = "internal";
   
         /* reinit */          /* reinit */
         log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);          log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
   
Line 2999 
Line 3091 
         argc -= optind;          argc -= optind;
   
         if (sign_op != NULL) {          if (sign_op != NULL) {
                 if (cert_principals == NULL) {                  if (cert_principals == NULL || *cert_principals == '\0') {
                         error("Too few arguments for sign/verify: "                          error("Too few arguments for sign/verify: "
                             "missing namespace");                              "missing namespace");
                         exit(1);                          exit(1);
Line 3011 
Line 3103 
                                 exit(1);                                  exit(1);
                         }                          }
                         return sign(identity_file, cert_principals, argc, argv);                          return sign(identity_file, cert_principals, argc, argv);
                   } else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
                           if (ca_key_path == NULL) {
                                   error("Too few arguments for check-novalidate: "
                                         "missing signature file");
                                   exit(1);
                           }
                           return verify(ca_key_path, cert_principals,
                                         NULL, NULL, NULL);
                 } else if (strncmp(sign_op, "verify", 6) == 0) {                  } else if (strncmp(sign_op, "verify", 6) == 0) {
                         if (ca_key_path == NULL) {                          if (ca_key_path == NULL) {
                                 error("Too few arguments for verify: "                                  error("Too few arguments for verify: "
Line 3087 
Line 3187 
                 do_convert_to(pw);                  do_convert_to(pw);
         if (convert_from)          if (convert_from)
                 do_convert_from(pw);                  do_convert_from(pw);
 #endif  #else /* WITH_OPENSSL */
           if (convert_to || convert_from)
                   fatal("key conversion disabled at compile time");
   #endif /* WITH_OPENSSL */
         if (print_public)          if (print_public)
                 do_print_public(pw);                  do_print_public(pw);
         if (rr_hostname != NULL) {          if (rr_hostname != NULL) {
Line 3178 
Line 3281 
         if (!quiet)          if (!quiet)
                 printf("Generating public/private %s key pair.\n",                  printf("Generating public/private %s key pair.\n",
                     key_type_name);                      key_type_name);
         if ((r = sshkey_generate(type, bits, &private)) != 0)          switch (type) {
                 fatal("sshkey_generate failed");          case KEY_ECDSA_SK:
           case KEY_ED25519_SK:
                   if (!quiet) {
                           printf("You may need to touch your security key "
                               "to authorize key generation.\n");
                   }
                   fflush(stdout);
                   if (sshsk_enroll(type, sk_provider,
                       cert_key_id == NULL ? "ssh:" : cert_key_id,
                       sk_flags, NULL, &private, NULL) != 0)
                           exit(1); /* error message already printed */
                   break;
           default:
                   if ((r = sshkey_generate(type, bits, &private)) != 0)
                           fatal("sshkey_generate failed");
                   break;
           }
         if ((r = sshkey_from_private(private, &public)) != 0)          if ((r = sshkey_from_private(private, &public)) != 0)
                 fatal("sshkey_from_private failed: %s\n", ssh_err(r));                  fatal("sshkey_from_private failed: %s\n", ssh_err(r));
   

Legend:
Removed from v.1.346  
changed lines
  Added in v.1.374