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

Diff for /src/usr.bin/ssh/kex.c between version 1.151 and 1.152

version 1.151, 2019/09/05 09:25:13 version 1.152, 2019/09/05 09:35:19
Line 334 
Line 334 
                 r = SSH_ERR_ALLOC_FAIL;                  r = SSH_ERR_ALLOC_FAIL;
                 goto out;                  goto out;
         }          }
         if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */          if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
                   error("%s: consume cookie: %s", __func__, ssh_err(r));
                 goto out;                  goto out;
           }
         /* extract kex init proposal strings */          /* extract kex init proposal strings */
         for (i = 0; i < PROPOSAL_MAX; i++) {          for (i = 0; i < PROPOSAL_MAX; i++) {
                 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)                  if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
                           error("%s: parse proposal %u: %s", __func__,
                               i, ssh_err(r));
                         goto out;                          goto out;
                   }
                 debug2("%s: %s", proposal_names[i], proposal[i]);                  debug2("%s: %s", proposal_names[i], proposal[i]);
         }          }
         /* first kex follows / reserved */          /* first kex follows / reserved */
         if ((r = sshbuf_get_u8(b, &v)) != 0 ||  /* first_kex_follows */          if ((r = sshbuf_get_u8(b, &v)) != 0 ||  /* first_kex_follows */
             (r = sshbuf_get_u32(b, &i)) != 0)   /* reserved */              (r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */
                   error("%s: parse: %s", __func__, ssh_err(r));
                 goto out;                  goto out;
           }
         if (first_kex_follows != NULL)          if (first_kex_follows != NULL)
                 *first_kex_follows = v;                  *first_kex_follows = v;
         debug2("first_kex_follows %d ", v);          debug2("first_kex_follows %d ", v);
Line 406 
Line 413 
             (r = sshpkt_put_u32(ssh, 1)) != 0 ||              (r = sshpkt_put_u32(ssh, 1)) != 0 ||
             (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||              (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
             (r = sshpkt_put_cstring(ssh, algs)) != 0 ||              (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
             (r = sshpkt_send(ssh)) != 0)              (r = sshpkt_send(ssh)) != 0) {
                   error("%s: compose: %s", __func__, ssh_err(r));
                 goto out;                  goto out;
           }
         /* success */          /* success */
         r = 0;          r = 0;
  out:   out:
Line 501 
Line 510 
         struct kex *kex = ssh->kex;          struct kex *kex = ssh->kex;
         int r;          int r;
   
         if (kex == NULL)          if (kex == NULL) {
                   error("%s: no hex", __func__);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
           }
         if (kex->flags & KEX_INIT_SENT)          if (kex->flags & KEX_INIT_SENT)
                 return 0;                  return 0;
         kex->done = 0;          kex->done = 0;
   
         /* generate a random cookie */          /* generate a random cookie */
         if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)          if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
                   error("%s: bad kex length: %zu < %d", __func__,
                       sshbuf_len(kex->my), KEX_COOKIE_LEN);
                 return SSH_ERR_INVALID_FORMAT;                  return SSH_ERR_INVALID_FORMAT;
         if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)          }
           if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {
                   error("%s: buffer error", __func__);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
           }
         arc4random_buf(cookie, KEX_COOKIE_LEN);          arc4random_buf(cookie, KEX_COOKIE_LEN);
   
         if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
             (r = sshpkt_putb(ssh, kex->my)) != 0 ||              (r = sshpkt_putb(ssh, kex->my)) != 0 ||
             (r = sshpkt_send(ssh)) != 0)              (r = sshpkt_send(ssh)) != 0) {
                   error("%s: compose reply: %s", __func__, ssh_err(r));
                 return r;                  return r;
           }
         debug("SSH2_MSG_KEXINIT sent");          debug("SSH2_MSG_KEXINIT sent");
         kex->flags |= KEX_INIT_SENT;          kex->flags |= KEX_INIT_SENT;
         return 0;          return 0;
Line 534 
Line 552 
         int r;          int r;
   
         debug("SSH2_MSG_KEXINIT received");          debug("SSH2_MSG_KEXINIT received");
         if (kex == NULL)          if (kex == NULL) {
                 return SSH_ERR_INVALID_ARGUMENT;                  error("%s: no hex", __func__);
                   return SSH_ERR_INTERNAL_ERROR;
           }
         ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);          ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
         ptr = sshpkt_ptr(ssh, &dlen);          ptr = sshpkt_ptr(ssh, &dlen);
         if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)          if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
                 return r;                  return r;
   
         /* discard packet */          /* discard packet */
         for (i = 0; i < KEX_COOKIE_LEN; i++)          for (i = 0; i < KEX_COOKIE_LEN; i++) {
                 if ((r = sshpkt_get_u8(ssh, NULL)) != 0)                  if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
                           error("%s: discard cookie: %s", __func__, ssh_err(r));
                         return r;                          return r;
         for (i = 0; i < PROPOSAL_MAX; i++)                  }
                 if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)          }
           for (i = 0; i < PROPOSAL_MAX; i++) {
                   if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
                           error("%s: discard proposal: %s", __func__, ssh_err(r));
                         return r;                          return r;
                   }
           }
         /*          /*
          * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported           * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
          * KEX method has the server move first, but a server might be using           * KEX method has the server move first, but a server might be using
Line 573 
Line 598 
         if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)          if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
                 return (kex->kex[kex->kex_type])(ssh);                  return (kex->kex[kex->kex_type])(ssh);
   
           error("%s: unknown kex type %u", __func__, kex->kex_type);
         return SSH_ERR_INTERNAL_ERROR;          return SSH_ERR_INTERNAL_ERROR;
 }  }
   
Line 706 
Line 732 
         if (name == NULL)          if (name == NULL)
                 return SSH_ERR_NO_CIPHER_ALG_MATCH;                  return SSH_ERR_NO_CIPHER_ALG_MATCH;
         if ((enc->cipher = cipher_by_name(name)) == NULL) {          if ((enc->cipher = cipher_by_name(name)) == NULL) {
                   error("%s: unsupported cipher %s", __func__, name);
                 free(name);                  free(name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
Line 727 
Line 754 
         if (name == NULL)          if (name == NULL)
                 return SSH_ERR_NO_MAC_ALG_MATCH;                  return SSH_ERR_NO_MAC_ALG_MATCH;
         if (mac_setup(mac, name) < 0) {          if (mac_setup(mac, name) < 0) {
                   error("%s: unsupported MAC %s", __func__, name);
                 free(name);                  free(name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
Line 750 
Line 778 
         } else if (strcmp(name, "none") == 0) {          } else if (strcmp(name, "none") == 0) {
                 comp->type = COMP_NONE;                  comp->type = COMP_NONE;
         } else {          } else {
                   error("%s: unsupported compression scheme %s", __func__, name);
                 free(name);                  free(name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
Line 767 
Line 796 
         debug("kex: algorithm: %s", k->name ? k->name : "(no match)");          debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
         if (k->name == NULL)          if (k->name == NULL)
                 return SSH_ERR_NO_KEX_ALG_MATCH;                  return SSH_ERR_NO_KEX_ALG_MATCH;
         if ((kexalg = kex_alg_by_name(k->name)) == NULL)          if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
                   error("%s: unsupported KEX method %s", __func__, k->name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
           }
         k->kex_type = kexalg->type;          k->kex_type = kexalg->type;
         k->hash_alg = kexalg->hash_alg;          k->hash_alg = kexalg->hash_alg;
         k->ec_nid = kexalg->ec_nid;          k->ec_nid = kexalg->ec_nid;
Line 785 
Line 816 
         if (k->hostkey_alg == NULL)          if (k->hostkey_alg == NULL)
                 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;                  return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
         k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);          k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
         if (k->hostkey_type == KEY_UNSPEC)          if (k->hostkey_type == KEY_UNSPEC) {
                   error("%s: unsupported hostkey algorithm %s", __func__,
                       k->hostkey_alg);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
           }
         k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);          k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
         return 0;          return 0;
 }  }
Line 955 
Line 989 
             kex->session_id_len) != 0 ||              kex->session_id_len) != 0 ||
             ssh_digest_final(hashctx, digest, mdsz) != 0) {              ssh_digest_final(hashctx, digest, mdsz) != 0) {
                 r = SSH_ERR_LIBCRYPTO_ERROR;                  r = SSH_ERR_LIBCRYPTO_ERROR;
                   error("%s: KEX hash failed", __func__);
                 goto out;                  goto out;
         }          }
         ssh_digest_free(hashctx);          ssh_digest_free(hashctx);
Line 971 
Line 1006 
                     ssh_digest_update(hashctx, hash, hashlen) != 0 ||                      ssh_digest_update(hashctx, hash, hashlen) != 0 ||
                     ssh_digest_update(hashctx, digest, have) != 0 ||                      ssh_digest_update(hashctx, digest, have) != 0 ||
                     ssh_digest_final(hashctx, digest + have, mdsz) != 0) {                      ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
                           error("%s: KDF failed", __func__);
                         r = SSH_ERR_LIBCRYPTO_ERROR;                          r = SSH_ERR_LIBCRYPTO_ERROR;
                         goto out;                          goto out;
                 }                  }
Line 1034 
Line 1070 
         *pubp = NULL;          *pubp = NULL;
         *prvp = NULL;          *prvp = NULL;
         if (kex->load_host_public_key == NULL ||          if (kex->load_host_public_key == NULL ||
             kex->load_host_private_key == NULL)              kex->load_host_private_key == NULL) {
                   error("%s: missing hostkey loader", __func__);
                 return SSH_ERR_INVALID_ARGUMENT;                  return SSH_ERR_INVALID_ARGUMENT;
           }
         *pubp = kex->load_host_public_key(kex->hostkey_type,          *pubp = kex->load_host_public_key(kex->hostkey_type,
             kex->hostkey_nid, ssh);              kex->hostkey_nid, ssh);
         *prvp = kex->load_host_private_key(kex->hostkey_type,          *prvp = kex->load_host_private_key(kex->hostkey_type,
Line 1050 
Line 1088 
 {  {
         struct kex *kex = ssh->kex;          struct kex *kex = ssh->kex;
   
         if (kex->verify_host_key == NULL)          if (kex->verify_host_key == NULL) {
                   error("%s: missing hostkey verifier", __func__);
                 return SSH_ERR_INVALID_ARGUMENT;                  return SSH_ERR_INVALID_ARGUMENT;
           }
         if (server_host_key->type != kex->hostkey_type ||          if (server_host_key->type != kex->hostkey_type ||
             (kex->hostkey_type == KEY_ECDSA &&              (kex->hostkey_type == KEY_ECDSA &&
             server_host_key->ecdsa_nid != kex->hostkey_nid))              server_host_key->ecdsa_nid != kex->hostkey_nid))

Legend:
Removed from v.1.151  
changed lines
  Added in v.1.152