[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.128 and 1.129

version 1.128, 2022/10/28 00:41:17 version 1.129, 2022/10/28 00:41:52
Line 704 
Line 704 
                 return SSH_ERR_KEY_TYPE_UNKNOWN;                  return SSH_ERR_KEY_TYPE_UNKNOWN;
   
         typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);          typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
         return impl->funcs->serialize_public(key, b, typename, opts);          if ((ret = sshbuf_put_cstring(b, typename)) != 0)
                   return ret;
           return impl->funcs->serialize_public(key, b, opts);
 }  }
   
 int  int
Line 1800 
Line 1802 
 }  }
   
 int  int
 sshkey_check_rsa_length(const struct sshkey *k, int min_size)  sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key)
 {  {
 #ifdef WITH_OPENSSL          /* Parse additional security-key application string */
         const BIGNUM *rsa_n;          if (sshbuf_get_cstring(b, &key->sk_application, NULL) != 0)
         int nbits;                  return SSH_ERR_INVALID_FORMAT;
   
         if (k == NULL || k->rsa == NULL ||  
             (k->type != KEY_RSA && k->type != KEY_RSA_CERT))  
                 return 0;  
         RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);  
         nbits = BN_num_bits(rsa_n);  
         if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||  
             (min_size > 0 && nbits < min_size))  
                 return SSH_ERR_KEY_LENGTH;  
 #endif /* WITH_OPENSSL */  
         return 0;          return 0;
 }  }
   
Line 1823 
Line 1815 
     int allow_cert)      int allow_cert)
 {  {
         int type, ret = SSH_ERR_INTERNAL_ERROR;          int type, ret = SSH_ERR_INTERNAL_ERROR;
         char *ktype = NULL, *curve = NULL, *xmss_name = NULL;          char *ktype = NULL;
         struct sshkey *key = NULL;          struct sshkey *key = NULL;
         size_t len;  
         u_char *pk = NULL;  
         struct sshbuf *copy;          struct sshbuf *copy;
 #ifdef WITH_OPENSSL          const struct sshkey_impl *impl;
         EC_POINT *q = NULL;  
         BIGNUM *rsa_n = NULL, *rsa_e = NULL;  
         BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;  
 #endif /* WITH_OPENSSL */  
   
 #ifdef DEBUG_PK /* XXX */  #ifdef DEBUG_PK /* XXX */
         sshbuf_dump(b, stderr);          sshbuf_dump(b, stderr);
Line 1853 
Line 1839 
                 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;                  ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
                 goto out;                  goto out;
         }          }
         switch (type) {          if ((impl = sshkey_impl_from_type(type)) == NULL) {
 #ifdef WITH_OPENSSL                  ret = SSH_ERR_KEY_TYPE_UNKNOWN;
         case KEY_RSA_CERT:                  goto out;
                 /* Skip nonce */          }
           if ((key = sshkey_new(type)) == NULL) {
                   ret = SSH_ERR_ALLOC_FAIL;
                   goto out;
           }
           if (sshkey_type_is_cert(type)) {
                   /* Skip nonce that preceeds all certificates */
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {                  if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
                         ret = SSH_ERR_INVALID_FORMAT;                          ret = SSH_ERR_INVALID_FORMAT;
                         goto out;                          goto out;
                 }                  }
                 /* FALLTHROUGH */  
         case KEY_RSA:  
                 if ((key = sshkey_new(type)) == NULL) {  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
                 if (sshbuf_get_bignum2(b, &rsa_e) != 0 ||  
                     sshbuf_get_bignum2(b, &rsa_n) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {  
                         ret = SSH_ERR_LIBCRYPTO_ERROR;  
                         goto out;  
                 }  
                 rsa_n = rsa_e = NULL; /* transferred */  
                 if ((ret = sshkey_check_rsa_length(key, 0)) != 0)  
                         goto out;  
 #ifdef DEBUG_PK  
                 RSA_print_fp(stderr, key->rsa, 8);  
 #endif  
                 break;  
         case KEY_DSA_CERT:  
                 /* Skip nonce */  
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 /* FALLTHROUGH */  
         case KEY_DSA:  
                 if ((key = sshkey_new(type)) == NULL) {  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
                 if (sshbuf_get_bignum2(b, &dsa_p) != 0 ||  
                     sshbuf_get_bignum2(b, &dsa_q) != 0 ||  
                     sshbuf_get_bignum2(b, &dsa_g) != 0 ||  
                     sshbuf_get_bignum2(b, &dsa_pub_key) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {  
                         ret = SSH_ERR_LIBCRYPTO_ERROR;  
                         goto out;  
                 }  
                 dsa_p = dsa_q = dsa_g = NULL; /* transferred */  
                 if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {  
                         ret = SSH_ERR_LIBCRYPTO_ERROR;  
                         goto out;  
                 }  
                 dsa_pub_key = NULL; /* transferred */  
 #ifdef DEBUG_PK  
                 DSA_print_fp(stderr, key->dsa, 8);  
 #endif  
                 break;  
         case KEY_ECDSA_CERT:  
         case KEY_ECDSA_SK_CERT:  
                 /* Skip nonce */  
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 /* FALLTHROUGH */  
         case KEY_ECDSA:  
         case KEY_ECDSA_SK:  
                 if ((key = sshkey_new(type)) == NULL) {  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
                 key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);  
                 if (sshbuf_get_cstring(b, &curve, NULL) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {  
                         ret = SSH_ERR_EC_CURVE_MISMATCH;  
                         goto out;  
                 }  
                 EC_KEY_free(key->ecdsa);  
                 if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))  
                     == NULL) {  
                         ret = SSH_ERR_EC_CURVE_INVALID;  
                         goto out;  
                 }  
                 if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
                 if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),  
                     q) != 0) {  
                         ret = SSH_ERR_KEY_INVALID_EC_VALUE;  
                         goto out;  
                 }  
                 if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {  
                         /* XXX assume it is a allocation error */  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
 #ifdef DEBUG_PK  
                 sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);  
 #endif  
                 if (type == KEY_ECDSA_SK || type == KEY_ECDSA_SK_CERT) {  
                         /* Parse additional security-key application string */  
                         if (sshbuf_get_cstring(b, &key->sk_application,  
                             NULL) != 0) {  
                                 ret = SSH_ERR_INVALID_FORMAT;  
                                 goto out;  
                         }  
 #ifdef DEBUG_PK  
                         fprintf(stderr, "App: %s\n", key->sk_application);  
 #endif  
                 }  
                 break;  
 #endif /* WITH_OPENSSL */  
         case KEY_ED25519_CERT:  
         case KEY_ED25519_SK_CERT:  
                 /* Skip nonce */  
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 /* FALLTHROUGH */  
         case KEY_ED25519:  
         case KEY_ED25519_SK:  
                 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)  
                         goto out;  
                 if (len != ED25519_PK_SZ) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 if ((key = sshkey_new(type)) == NULL) {  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
                 if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) {  
                         /* Parse additional security-key application string */  
                         if (sshbuf_get_cstring(b, &key->sk_application,  
                             NULL) != 0) {  
                                 ret = SSH_ERR_INVALID_FORMAT;  
                                 goto out;  
                         }  
 #ifdef DEBUG_PK  
                         fprintf(stderr, "App: %s\n", key->sk_application);  
 #endif  
                 }  
                 key->ed25519_pk = pk;  
                 pk = NULL;  
                 break;  
 #ifdef WITH_XMSS  
         case KEY_XMSS_CERT:  
                 /* Skip nonce */  
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 /* FALLTHROUGH */  
         case KEY_XMSS:  
                 if ((ret = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0)  
                         goto out;  
                 if ((key = sshkey_new(type)) == NULL) {  
                         ret = SSH_ERR_ALLOC_FAIL;  
                         goto out;  
                 }  
                 if ((ret = sshkey_xmss_init(key, xmss_name)) != 0)  
                         goto out;  
                 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)  
                         goto out;  
                 if (len == 0 || len != sshkey_xmss_pklen(key)) {  
                         ret = SSH_ERR_INVALID_FORMAT;  
                         goto out;  
                 }  
                 key->xmss_pk = pk;  
                 pk = NULL;  
                 if (type != KEY_XMSS_CERT &&  
                     (ret = sshkey_xmss_deserialize_pk_info(key, b)) != 0)  
                         goto out;  
                 break;  
 #endif /* WITH_XMSS */  
         case KEY_UNSPEC:  
         default:  
                 ret = SSH_ERR_KEY_TYPE_UNKNOWN;  
                 goto out;  
         }          }
           if ((ret = impl->funcs->deserialize_public(ktype, b, key)) != 0)
                   goto out;
   
         /* Parse certificate potion */          /* Parse certificate potion */
         if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)          if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
Line 2065 
Line 1873 
  out:   out:
         sshbuf_free(copy);          sshbuf_free(copy);
         sshkey_free(key);          sshkey_free(key);
         free(xmss_name);  
         free(ktype);          free(ktype);
         free(curve);  
         free(pk);  
 #ifdef WITH_OPENSSL  
         EC_POINT_free(q);  
         BN_clear_free(rsa_n);  
         BN_clear_free(rsa_e);  
         BN_clear_free(dsa_p);  
         BN_clear_free(dsa_q);  
         BN_clear_free(dsa_g);  
         BN_clear_free(dsa_pub_key);  
 #endif /* WITH_OPENSSL */  
         return ret;          return ret;
 }  }
   

Legend:
Removed from v.1.128  
changed lines
  Added in v.1.129