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

Diff for /src/usr.bin/ssh/sshkey.c between version 1.122 and 1.123

version 1.122, 2022/09/17 10:30:45 version 1.123, 2022/10/28 00:35:40
Line 87 
Line 87 
     struct sshkey **keyp, int allow_cert);      struct sshkey **keyp, int allow_cert);
   
 /* Supported key types */  /* Supported key types */
 struct keytype {  extern const struct sshkey_impl sshkey_ed25519_impl;
         const char *name;  extern const struct sshkey_impl sshkey_ed25519_cert_impl;
         const char *shortname;  extern const struct sshkey_impl sshkey_ed25519_sk_impl;
         const char *sigalg;  extern const struct sshkey_impl sshkey_ed25519_sk_cert_impl;
         int type;  #ifdef WITH_OPENSSL
         int nid;  extern const struct sshkey_impl sshkey_ecdsa_sk_impl;
         int cert;  extern const struct sshkey_impl sshkey_ecdsa_sk_cert_impl;
         int sigonly;  extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl;
 };  extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl;
 static const struct keytype keytypes[] = {  extern const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl;
         { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },  extern const struct sshkey_impl sshkey_ecdsa_nistp384_impl;
         { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,  extern const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl;
             KEY_ED25519_CERT, 0, 1, 0 },  extern const struct sshkey_impl sshkey_ecdsa_nistp521_impl;
         { "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL,  extern const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl;
             KEY_ED25519_SK, 0, 0, 0 },  extern const struct sshkey_impl sshkey_rsa_impl;
         { "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL,  extern const struct sshkey_impl sshkey_rsa_cert_impl;
             KEY_ED25519_SK_CERT, 0, 1, 0 },  extern const struct sshkey_impl sshkey_rsa_sha256_impl;
   extern const struct sshkey_impl sshkey_rsa_sha256_cert_impl;
   extern const struct sshkey_impl sshkey_rsa_sha512_impl;
   extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl;
   extern const struct sshkey_impl sshkey_dss_impl;
   extern const struct sshkey_impl sshkey_dsa_cert_impl;
   #endif /* WITH_OPENSSL */
 #ifdef WITH_XMSS  #ifdef WITH_XMSS
         { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },  extern const struct sshkey_impl sshkey_xmss_impl;
         { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,  extern const struct sshkey_impl sshkey_xmss_cert_impl;
             KEY_XMSS_CERT, 0, 1, 0 },  #endif
 #endif /* WITH_XMSS */  
   const struct sshkey_impl * const keyimpls[] = {
           &sshkey_ed25519_impl,
           &sshkey_ed25519_cert_impl,
           &sshkey_ed25519_sk_impl,
           &sshkey_ed25519_sk_cert_impl,
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
         { "ssh-rsa", "RSA", NULL, KEY_RSA, 0, 0, 0 },          &sshkey_ecdsa_nistp256_impl,
         { "rsa-sha2-256", "RSA", NULL, KEY_RSA, 0, 0, 1 },          &sshkey_ecdsa_nistp256_cert_impl,
         { "rsa-sha2-512", "RSA", NULL, KEY_RSA, 0, 0, 1 },          &sshkey_ecdsa_nistp384_impl,
         { "ssh-dss", "DSA", NULL, KEY_DSA, 0, 0, 0 },          &sshkey_ecdsa_nistp384_cert_impl,
         { "ecdsa-sha2-nistp256", "ECDSA", NULL,          &sshkey_ecdsa_nistp521_impl,
             KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },          &sshkey_ecdsa_nistp521_cert_impl,
         { "ecdsa-sha2-nistp384", "ECDSA", NULL,          &sshkey_ecdsa_sk_impl,
             KEY_ECDSA, NID_secp384r1, 0, 0 },          &sshkey_ecdsa_sk_cert_impl,
         { "ecdsa-sha2-nistp521", "ECDSA", NULL,          &sshkey_ecdsa_sk_webauthn_impl,
             KEY_ECDSA, NID_secp521r1, 0, 0 },          &sshkey_dss_impl,
         { "sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,          &sshkey_dsa_cert_impl,
             KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 0 },          &sshkey_rsa_impl,
         { "webauthn-sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,          &sshkey_rsa_cert_impl,
             KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 1 },          &sshkey_rsa_sha256_impl,
         { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,          &sshkey_rsa_sha256_cert_impl,
             KEY_RSA_CERT, 0, 1, 0 },          &sshkey_rsa_sha512_impl,
         { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",          &sshkey_rsa_sha512_cert_impl,
             "rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },  
         { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",  
             "rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },  
         { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,  
             KEY_DSA_CERT, 0, 1, 0 },  
         { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", NULL,  
             KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },  
         { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", NULL,  
             KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },  
         { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL,  
             KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },  
         { "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-SK-CERT", NULL,  
             KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 },  
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
         { NULL, NULL, NULL, -1, -1, 0, 0 }  #ifdef WITH_XMSS
           &sshkey_xmss_impl,
           &sshkey_xmss_cert_impl,
   #endif
           NULL
 };  };
   
   static const struct sshkey_impl *
   sshkey_impl_from_type(int type)
   {
           int i;
   
           for (i = 0; keyimpls[i] != NULL; i++) {
                   if (keyimpls[i]->type == type)
                           return keyimpls[i];
           }
           return NULL;
   }
   
   static const struct sshkey_impl *
   sshkey_impl_from_type_nid(int type, int nid)
   {
           int i;
   
           for (i = 0; keyimpls[i] != NULL; i++) {
                   if (keyimpls[i]->type == type &&
                       (keyimpls[i]->nid == 0 || keyimpls[i]->nid == nid))
                           return keyimpls[i];
           }
           return NULL;
   }
   
 const char *  const char *
 sshkey_type(const struct sshkey *k)  sshkey_type(const struct sshkey *k)
 {  {
         const struct keytype *kt;          const struct sshkey_impl *impl;
   
         for (kt = keytypes; kt->type != -1; kt++) {          if ((impl = sshkey_impl_from_type(k->type)) == NULL)
                 if (kt->type == k->type)                  return "unknown";
                         return kt->shortname;          return impl->shortname;
         }  
         return "unknown";  
 }  }
   
 static const char *  static const char *
 sshkey_ssh_name_from_type_nid(int type, int nid)  sshkey_ssh_name_from_type_nid(int type, int nid)
 {  {
         const struct keytype *kt;          const struct sshkey_impl *impl;
   
         for (kt = keytypes; kt->type != -1; kt++) {          if ((impl = sshkey_impl_from_type_nid(type, nid)) == NULL)
                 if (kt->type == type && (kt->nid == 0 || kt->nid == nid))                  return "ssh-unknown";
                         return kt->name;          return impl->name;
         }  
         return "ssh-unknown";  
 }  }
   
 int  int
 sshkey_type_is_cert(int type)  sshkey_type_is_cert(int type)
 {  {
         const struct keytype *kt;          const struct sshkey_impl *impl;
   
         for (kt = keytypes; kt->type != -1; kt++) {          if ((impl = sshkey_impl_from_type(type)) == NULL)
                 if (kt->type == type)                  return 0;
                         return kt->cert;          return impl->cert;
         }  
         return 0;  
 }  }
   
 const char *  const char *
Line 196 
Line 217 
 int  int
 sshkey_type_from_name(const char *name)  sshkey_type_from_name(const char *name)
 {  {
         const struct keytype *kt;          int i;
           const struct sshkey_impl *impl;
   
         for (kt = keytypes; kt->type != -1; kt++) {          for (i = 0; keyimpls[i] != NULL; i++) {
                   impl = keyimpls[i];
                 /* Only allow shortname matches for plain key types */                  /* Only allow shortname matches for plain key types */
                 if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||                  if ((impl->name != NULL && strcmp(name, impl->name) == 0) ||
                     (!kt->cert && strcasecmp(kt->shortname, name) == 0))                      (!impl->cert && strcasecmp(impl->shortname, name) == 0))
                         return kt->type;                          return impl->type;
         }          }
         return KEY_UNSPEC;          return KEY_UNSPEC;
 }  }
Line 223 
Line 246 
 int  int
 sshkey_ecdsa_nid_from_name(const char *name)  sshkey_ecdsa_nid_from_name(const char *name)
 {  {
         const struct keytype *kt;          int i;
   
         for (kt = keytypes; kt->type != -1; kt++) {          for (i = 0; keyimpls[i] != NULL; i++) {
                 if (!key_type_is_ecdsa_variant(kt->type))                  if (!key_type_is_ecdsa_variant(keyimpls[i]->type))
                         continue;                          continue;
                 if (kt->name != NULL && strcmp(name, kt->name) == 0)                  if (keyimpls[i]->name != NULL &&
                         return kt->nid;                      strcmp(name, keyimpls[i]->name) == 0)
                           return keyimpls[i]->nid;
         }          }
         return -1;          return -1;
 }  }
Line 261 
Line 285 
 sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)  sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
 {  {
         char *tmp, *ret = NULL;          char *tmp, *ret = NULL;
         size_t nlen, rlen = 0;          size_t i, nlen, rlen = 0;
         const struct keytype *kt;          const struct sshkey_impl *impl;
   
         for (kt = keytypes; kt->type != -1; kt++) {          for (i = 0; keyimpls[i] != NULL; i++) {
                 if (kt->name == NULL)                  impl = keyimpls[i];
                   if (impl->name == NULL)
                         continue;                          continue;
                 if (!include_sigonly && kt->sigonly)                  if (!include_sigonly && impl->sigonly)
                         continue;                          continue;
                 if ((certs_only && !kt->cert) || (plain_only && kt->cert))                  if ((certs_only && !impl->cert) || (plain_only && impl->cert))
                         continue;                          continue;
                 if (ret != NULL)                  if (ret != NULL)
                         ret[rlen++] = sep;                          ret[rlen++] = sep;
                 nlen = strlen(kt->name);                  nlen = strlen(impl->name);
                 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {                  if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
                         free(ret);                          free(ret);
                         return NULL;                          return NULL;
                 }                  }
                 ret = tmp;                  ret = tmp;
                 memcpy(ret + rlen, kt->name, nlen + 1);                  memcpy(ret + rlen, impl->name, nlen + 1);
                 rlen += nlen;                  rlen += nlen;
         }          }
         return ret;          return ret;
Line 289 
Line 314 
 sshkey_names_valid2(const char *names, int allow_wildcard)  sshkey_names_valid2(const char *names, int allow_wildcard)
 {  {
         char *s, *cp, *p;          char *s, *cp, *p;
         const struct keytype *kt;          const struct sshkey_impl *impl;
         int type;          int i, type;
   
         if (names == NULL || strcmp(names, "") == 0)          if (names == NULL || strcmp(names, "") == 0)
                 return 0;                  return 0;
Line 306 
Line 331 
                                  * If any has a positive or negative match then                                   * If any has a positive or negative match then
                                  * the component is accepted.                                   * the component is accepted.
                                  */                                   */
                                 for (kt = keytypes; kt->type != -1; kt++) {                                  impl = NULL;
                                         if (match_pattern_list(kt->name,                                  for (i = 0; keyimpls[i] != NULL; i++) {
                                             p, 0) != 0)                                          if (match_pattern_list(
                                               keyimpls[i]->name, p, 0) != 0) {
                                                   impl = keyimpls[i];
                                                 break;                                                  break;
                                           }
                                 }                                  }
                                 if (kt->type != -1)                                  if (impl != NULL)
                                         continue;                                          continue;
                         }                          }
                         free(s);                          free(s);
Line 325 
Line 353 
 u_int  u_int
 sshkey_size(const struct sshkey *k)  sshkey_size(const struct sshkey *k)
 {  {
 #ifdef WITH_OPENSSL          const struct sshkey_impl *impl;
         const BIGNUM *rsa_n, *dsa_p;  
 #endif /* WITH_OPENSSL */  
   
         switch (k->type) {          if ((impl = sshkey_impl_from_type_nid(k->type, k->ecdsa_nid)) == NULL)
 #ifdef WITH_OPENSSL                  return 0;
         case KEY_RSA:          if (impl->funcs->size != NULL)
         case KEY_RSA_CERT:                  return impl->funcs->size(k);
                 if (k->rsa == NULL)          return impl->keybits;
                         return 0;  
                 RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);  
                 return BN_num_bits(rsa_n);  
         case KEY_DSA:  
         case KEY_DSA_CERT:  
                 if (k->dsa == NULL)  
                         return 0;  
                 DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);  
                 return BN_num_bits(dsa_p);  
         case KEY_ECDSA:  
         case KEY_ECDSA_CERT:  
         case KEY_ECDSA_SK:  
         case KEY_ECDSA_SK_CERT:  
                 return sshkey_curve_nid_to_bits(k->ecdsa_nid);  
 #endif /* WITH_OPENSSL */  
         case KEY_ED25519:  
         case KEY_ED25519_CERT:  
         case KEY_ED25519_SK:  
         case KEY_ED25519_SK_CERT:  
         case KEY_XMSS:  
         case KEY_XMSS_CERT:  
                 return 256;     /* XXX */  
         }  
         return 0;  
 }  }
   
 static int  static int
 sshkey_type_is_valid_ca(int type)  sshkey_type_is_valid_ca(int type)
 {  {
         switch (type) {          const struct sshkey_impl *impl;
         case KEY_RSA:  
         case KEY_DSA:          if ((impl = sshkey_impl_from_type(type)) == NULL)
         case KEY_ECDSA:  
         case KEY_ECDSA_SK:  
         case KEY_ED25519:  
         case KEY_ED25519_SK:  
         case KEY_XMSS:  
                 return 1;  
         default:  
                 return 0;                  return 0;
         }          /* All non-certificate types may act as CAs */
           return !impl->cert;
 }  }
   
 int  int
Line 544 
Line 540 
 sshkey_new(int type)  sshkey_new(int type)
 {  {
         struct sshkey *k;          struct sshkey *k;
 #ifdef WITH_OPENSSL          const struct sshkey_impl *impl = NULL;
         RSA *rsa;  
         DSA *dsa;  
 #endif /* WITH_OPENSSL */  
   
           if (type != KEY_UNSPEC &&
               (impl = sshkey_impl_from_type(type)) == NULL)
                   return NULL;
   
           /* All non-certificate types may act as CAs */
         if ((k = calloc(1, sizeof(*k))) == NULL)          if ((k = calloc(1, sizeof(*k))) == NULL)
                 return NULL;                  return NULL;
         k->type = type;          k->type = type;
         k->ecdsa = NULL;  
         k->ecdsa_nid = -1;          k->ecdsa_nid = -1;
         k->dsa = NULL;          if (impl != NULL && impl->funcs->alloc != NULL) {
         k->rsa = NULL;                  if (impl->funcs->alloc(k) != 0) {
         k->cert = NULL;  
         k->ed25519_sk = NULL;  
         k->ed25519_pk = NULL;  
         k->xmss_sk = NULL;  
         k->xmss_pk = NULL;  
         switch (k->type) {  
 #ifdef WITH_OPENSSL  
         case KEY_RSA:  
         case KEY_RSA_CERT:  
                 if ((rsa = RSA_new()) == NULL) {  
                         free(k);                          free(k);
                         return NULL;                          return NULL;
                 }                  }
                 k->rsa = rsa;  
                 break;  
         case KEY_DSA:  
         case KEY_DSA_CERT:  
                 if ((dsa = DSA_new()) == NULL) {  
                         free(k);  
                         return NULL;  
                 }  
                 k->dsa = dsa;  
                 break;  
         case KEY_ECDSA:  
         case KEY_ECDSA_CERT:  
         case KEY_ECDSA_SK:  
         case KEY_ECDSA_SK_CERT:  
                 /* Cannot do anything until we know the group */  
                 break;  
 #endif /* WITH_OPENSSL */  
         case KEY_ED25519:  
         case KEY_ED25519_CERT:  
         case KEY_ED25519_SK:  
         case KEY_ED25519_SK_CERT:  
         case KEY_XMSS:  
         case KEY_XMSS_CERT:  
                 /* no need to prealloc */  
                 break;  
         case KEY_UNSPEC:  
                 break;  
         default:  
                 free(k);  
                 return NULL;  
         }          }
   
         if (sshkey_is_cert(k)) {          if (sshkey_is_cert(k)) {
                 if ((k->cert = cert_new()) == NULL) {                  if ((k->cert = cert_new()) == NULL) {
                         sshkey_free(k);                          sshkey_free(k);
Line 614 
Line 570 
 void  void
 sshkey_free(struct sshkey *k)  sshkey_free(struct sshkey *k)
 {  {
           const struct sshkey_impl *impl;
   
         if (k == NULL)          if (k == NULL)
                 return;                  return;
         switch (k->type) {          if ((impl = sshkey_impl_from_type(k->type)) != NULL &&
 #ifdef WITH_OPENSSL              impl->funcs->cleanup != NULL)
         case KEY_RSA:                  impl->funcs->cleanup(k);
         case KEY_RSA_CERT:  
                 RSA_free(k->rsa);  
                 k->rsa = NULL;  
                 break;  
         case KEY_DSA:  
         case KEY_DSA_CERT:  
                 DSA_free(k->dsa);  
                 k->dsa = NULL;  
                 break;  
         case KEY_ECDSA_SK:  
         case KEY_ECDSA_SK_CERT:  
                 free(k->sk_application);  
                 sshbuf_free(k->sk_key_handle);  
                 sshbuf_free(k->sk_reserved);  
                 /* FALLTHROUGH */  
         case KEY_ECDSA:  
         case KEY_ECDSA_CERT:  
                 EC_KEY_free(k->ecdsa);  
                 k->ecdsa = NULL;  
                 break;  
 #endif /* WITH_OPENSSL */  
         case KEY_ED25519_SK:  
         case KEY_ED25519_SK_CERT:  
                 free(k->sk_application);  
                 sshbuf_free(k->sk_key_handle);  
                 sshbuf_free(k->sk_reserved);  
                 /* FALLTHROUGH */  
         case KEY_ED25519:  
         case KEY_ED25519_CERT:  
                 freezero(k->ed25519_pk, ED25519_PK_SZ);  
                 k->ed25519_pk = NULL;  
                 freezero(k->ed25519_sk, ED25519_SK_SZ);  
                 k->ed25519_sk = NULL;  
                 break;  
 #ifdef WITH_XMSS  
         case KEY_XMSS:  
         case KEY_XMSS_CERT:  
                 freezero(k->xmss_pk, sshkey_xmss_pklen(k));  
                 k->xmss_pk = NULL;  
                 freezero(k->xmss_sk, sshkey_xmss_sklen(k));  
                 k->xmss_sk = NULL;  
                 sshkey_xmss_free_state(k);  
                 free(k->xmss_name);  
                 k->xmss_name = NULL;  
                 free(k->xmss_filename);  
                 k->xmss_filename = NULL;  
                 break;  
 #endif /* WITH_XMSS */  
         case KEY_UNSPEC:  
                 break;  
         default:  
                 break;  
         }  
         if (sshkey_is_cert(k))          if (sshkey_is_cert(k))
                 cert_free(k->cert);                  cert_free(k->cert);
         freezero(k->shielded_private, k->shielded_len);          freezero(k->shielded_private, k->shielded_len);
Line 1284 
Line 1189 
 static int  static int
 peek_type_nid(const char *s, size_t l, int *nid)  peek_type_nid(const char *s, size_t l, int *nid)
 {  {
         const struct keytype *kt;          const struct sshkey_impl *impl;
           int i;
   
         for (kt = keytypes; kt->type != -1; kt++) {          for (i = 0; keyimpls[i] != NULL; i++) {
                 if (kt->name == NULL || strlen(kt->name) != l)                  impl = keyimpls[i];
                   if (impl->name == NULL || strlen(impl->name) != l)
                         continue;                          continue;
                 if (memcmp(s, kt->name, l) == 0) {                  if (memcmp(s, impl->name, l) == 0) {
                         *nid = -1;                          *nid = -1;
                         if (key_type_is_ecdsa_variant(kt->type))                          if (key_type_is_ecdsa_variant(impl->type))
                                 *nid = kt->nid;                                  *nid = impl->nid;
                         return kt->type;                          return impl->type;
                 }                  }
         }          }
         return KEY_UNSPEC;          return KEY_UNSPEC;
Line 2685 
Line 2592 
 const char *  const char *
 sshkey_sigalg_by_name(const char *name)  sshkey_sigalg_by_name(const char *name)
 {  {
         const struct keytype *kt;          const struct sshkey_impl *impl;
           int i;
   
         for (kt = keytypes; kt->type != -1; kt++) {          for (i = 0; keyimpls[i] != NULL; i++) {
                 if (strcmp(kt->name, name) != 0)                  impl = keyimpls[i];
                   if (strcmp(impl->name, name) != 0)
                         continue;                          continue;
                 if (kt->sigalg != NULL)                  if (impl->sigalg != NULL)
                         return kt->sigalg;                          return impl->sigalg;
                 if (!kt->cert)                  if (!impl->cert)
                         return kt->name;                          return impl->name;
                 return sshkey_ssh_name_from_type_nid(                  return sshkey_ssh_name_from_type_nid(
                     sshkey_type_plain(kt->type), kt->nid);                      sshkey_type_plain(impl->type), impl->nid);
         }          }
         return NULL;          return NULL;
 }  }

Legend:
Removed from v.1.122  
changed lines
  Added in v.1.123