1 /* $NetBSD: kex.c,v 1.36 2024/07/08 22:33:43 christos Exp $ */ 2 /* $OpenBSD: kex.c,v 1.186 2024/05/17 00:30:23 djm Exp $ */ 3 4 /* 5 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "includes.h" 29 __RCSID("$NetBSD: kex.c,v 1.36 2024/07/08 22:33:43 christos Exp $"); 30 31 #include <sys/param.h> /* MAX roundup */ 32 #include <sys/types.h> 33 #include <errno.h> 34 #include <signal.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 #include <poll.h> 40 41 #ifdef WITH_OPENSSL 42 #include <openssl/crypto.h> 43 #include <openssl/dh.h> 44 #endif 45 46 #include "ssh.h" 47 #include "ssh2.h" 48 #include "atomicio.h" 49 #include "version.h" 50 #include "packet.h" 51 #include "compat.h" 52 #include "cipher.h" 53 #include "sshkey.h" 54 #include "kex.h" 55 #include "log.h" 56 #include "mac.h" 57 #include "match.h" 58 #include "misc.h" 59 #include "dispatch.h" 60 #include "packet.h" 61 #include "monitor.h" 62 #include "myproposal.h" 63 64 #include "ssherr.h" 65 #include "sshbuf.h" 66 #include "digest.h" 67 #include "xmalloc.h" 68 69 /* prototype */ 70 static int kex_choose_conf(struct ssh *, uint32_t seq); 71 static int kex_input_newkeys(int, u_int32_t, struct ssh *); 72 73 static const char * const proposal_names[PROPOSAL_MAX] = { 74 "KEX algorithms", 75 "host key algorithms", 76 "ciphers ctos", 77 "ciphers stoc", 78 "MACs ctos", 79 "MACs stoc", 80 "compression ctos", 81 "compression stoc", 82 "languages ctos", 83 "languages stoc", 84 }; 85 86 /* 87 * Fill out a proposal array with dynamically allocated values, which may 88 * be modified as required for compatibility reasons. 89 * Any of the options may be NULL, in which case the default is used. 90 * Array contents must be freed by calling kex_proposal_free_entries. 91 */ 92 void 93 kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], 94 const char *kexalgos, const char *ciphers, const char *macs, 95 const char *comp, const char *hkalgs) 96 { 97 const char *defpropserver[PROPOSAL_MAX] = { KEX_SERVER }; 98 const char *defpropclient[PROPOSAL_MAX] = { KEX_CLIENT }; 99 const char **defprop = ssh->kex->server ? defpropserver : defpropclient; 100 u_int i; 101 char *cp; 102 103 if (prop == NULL) 104 fatal_f("proposal missing"); 105 106 /* Append EXT_INFO signalling to KexAlgorithms */ 107 if (kexalgos == NULL) 108 kexalgos = defprop[PROPOSAL_KEX_ALGS]; 109 if ((cp = kex_names_cat(kexalgos, ssh->kex->server ? 110 "ext-info-s,kex-strict-s-v00@openssh.com" : 111 "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL) 112 fatal_f("kex_names_cat"); 113 114 for (i = 0; i < PROPOSAL_MAX; i++) { 115 switch(i) { 116 case PROPOSAL_KEX_ALGS: 117 prop[i] = compat_kex_proposal(ssh, cp); 118 break; 119 case PROPOSAL_ENC_ALGS_CTOS: 120 case PROPOSAL_ENC_ALGS_STOC: 121 prop[i] = xstrdup(ciphers ? ciphers : defprop[i]); 122 break; 123 case PROPOSAL_MAC_ALGS_CTOS: 124 case PROPOSAL_MAC_ALGS_STOC: 125 prop[i] = xstrdup(macs ? macs : defprop[i]); 126 break; 127 case PROPOSAL_COMP_ALGS_CTOS: 128 case PROPOSAL_COMP_ALGS_STOC: 129 prop[i] = xstrdup(comp ? comp : defprop[i]); 130 break; 131 case PROPOSAL_SERVER_HOST_KEY_ALGS: 132 prop[i] = xstrdup(hkalgs ? hkalgs : defprop[i]); 133 break; 134 default: 135 prop[i] = xstrdup(defprop[i]); 136 } 137 } 138 free(cp); 139 } 140 141 void 142 kex_proposal_free_entries(char *prop[PROPOSAL_MAX]) 143 { 144 u_int i; 145 146 for (i = 0; i < PROPOSAL_MAX; i++) 147 free(prop[i]); 148 } 149 150 /* put algorithm proposal into buffer */ 151 int 152 kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) 153 { 154 u_int i; 155 int r; 156 157 sshbuf_reset(b); 158 159 /* 160 * add a dummy cookie, the cookie will be overwritten by 161 * kex_send_kexinit(), each time a kexinit is set 162 */ 163 for (i = 0; i < KEX_COOKIE_LEN; i++) { 164 if ((r = sshbuf_put_u8(b, 0)) != 0) 165 return r; 166 } 167 for (i = 0; i < PROPOSAL_MAX; i++) { 168 if ((r = sshbuf_put_cstring(b, proposal[i])) != 0) 169 return r; 170 } 171 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */ 172 (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */ 173 return r; 174 return 0; 175 } 176 177 /* parse buffer and return algorithm proposal */ 178 int 179 kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp) 180 { 181 struct sshbuf *b = NULL; 182 u_char v; 183 u_int i; 184 char **proposal = NULL; 185 int r; 186 187 *propp = NULL; 188 if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL) 189 return SSH_ERR_ALLOC_FAIL; 190 if ((b = sshbuf_fromb(raw)) == NULL) { 191 r = SSH_ERR_ALLOC_FAIL; 192 goto out; 193 } 194 if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */ 195 error_fr(r, "consume cookie"); 196 goto out; 197 } 198 /* extract kex init proposal strings */ 199 for (i = 0; i < PROPOSAL_MAX; i++) { 200 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) { 201 error_fr(r, "parse proposal %u", i); 202 goto out; 203 } 204 debug2("%s: %s", proposal_names[i], proposal[i]); 205 } 206 /* first kex follows / reserved */ 207 if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */ 208 (r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */ 209 error_fr(r, "parse"); 210 goto out; 211 } 212 if (first_kex_follows != NULL) 213 *first_kex_follows = v; 214 debug2("first_kex_follows %d ", v); 215 debug2("reserved %u ", i); 216 r = 0; 217 *propp = proposal; 218 out: 219 if (r != 0 && proposal != NULL) 220 kex_prop_free(proposal); 221 sshbuf_free(b); 222 return r; 223 } 224 225 void 226 kex_prop_free(char **proposal) 227 { 228 u_int i; 229 230 if (proposal == NULL) 231 return; 232 for (i = 0; i < PROPOSAL_MAX; i++) 233 free(proposal[i]); 234 free(proposal); 235 } 236 237 int 238 kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh) 239 { 240 int r; 241 242 /* If in strict mode, any unexpected message is an error */ 243 if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) { 244 ssh_packet_disconnect(ssh, "strict KEX violation: " 245 "unexpected packet type %u (seqnr %u)", type, seq); 246 } 247 error_f("type %u seq %u", type, seq); 248 if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || 249 (r = sshpkt_put_u32(ssh, seq)) != 0 || 250 (r = sshpkt_send(ssh)) != 0) 251 return r; 252 return 0; 253 } 254 255 static void 256 kex_reset_dispatch(struct ssh *ssh) 257 { 258 ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN, 259 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); 260 } 261 262 void 263 kex_set_server_sig_algs(struct ssh *ssh, const char *allowed_algs) 264 { 265 char *alg, *oalgs, *algs, *sigalgs; 266 const char *sigalg; 267 268 /* 269 * NB. allowed algorithms may contain certificate algorithms that 270 * map to a specific plain signature type, e.g. 271 * rsa-sha2-512-cert-v01@openssh.com => rsa-sha2-512 272 * We need to be careful here to match these, retain the mapping 273 * and only add each signature algorithm once. 274 */ 275 if ((sigalgs = sshkey_alg_list(0, 1, 1, ',')) == NULL) 276 fatal_f("sshkey_alg_list failed"); 277 oalgs = algs = xstrdup(allowed_algs); 278 free(ssh->kex->server_sig_algs); 279 ssh->kex->server_sig_algs = NULL; 280 for ((alg = strsep(&algs, ",")); alg != NULL && *alg != '\0'; 281 (alg = strsep(&algs, ","))) { 282 if ((sigalg = sshkey_sigalg_by_name(alg)) == NULL) 283 continue; 284 if (!kex_has_any_alg(sigalg, sigalgs)) 285 continue; 286 /* Don't add an algorithm twice. */ 287 if (ssh->kex->server_sig_algs != NULL && 288 kex_has_any_alg(sigalg, ssh->kex->server_sig_algs)) 289 continue; 290 xextendf(&ssh->kex->server_sig_algs, ",", "%s", sigalg); 291 } 292 free(oalgs); 293 free(sigalgs); 294 if (ssh->kex->server_sig_algs == NULL) 295 ssh->kex->server_sig_algs = xstrdup(""); 296 } 297 298 static int 299 kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) 300 { 301 int r; 302 303 if (ssh->kex->server_sig_algs == NULL && 304 (ssh->kex->server_sig_algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) 305 return SSH_ERR_ALLOC_FAIL; 306 if ((r = sshbuf_put_u32(m, 3)) != 0 || 307 (r = sshbuf_put_cstring(m, "server-sig-algs")) != 0 || 308 (r = sshbuf_put_cstring(m, ssh->kex->server_sig_algs)) != 0 || 309 (r = sshbuf_put_cstring(m, 310 "publickey-hostbound@openssh.com")) != 0 || 311 (r = sshbuf_put_cstring(m, "0")) != 0 || 312 (r = sshbuf_put_cstring(m, "ping@openssh.com")) != 0 || 313 (r = sshbuf_put_cstring(m, "0")) != 0) { 314 error_fr(r, "compose"); 315 return r; 316 } 317 return 0; 318 } 319 320 static int 321 kex_compose_ext_info_client(struct ssh *ssh, struct sshbuf *m) 322 { 323 int r; 324 325 if ((r = sshbuf_put_u32(m, 1)) != 0 || 326 (r = sshbuf_put_cstring(m, "ext-info-in-auth@openssh.com")) != 0 || 327 (r = sshbuf_put_cstring(m, "0")) != 0) { 328 error_fr(r, "compose"); 329 goto out; 330 } 331 /* success */ 332 r = 0; 333 out: 334 return r; 335 } 336 337 static int 338 kex_maybe_send_ext_info(struct ssh *ssh) 339 { 340 int r; 341 struct sshbuf *m = NULL; 342 343 if ((ssh->kex->flags & KEX_INITIAL) == 0) 344 return 0; 345 if (!ssh->kex->ext_info_c && !ssh->kex->ext_info_s) 346 return 0; 347 348 /* Compose EXT_INFO packet. */ 349 if ((m = sshbuf_new()) == NULL) 350 fatal_f("sshbuf_new failed"); 351 if (ssh->kex->ext_info_c && 352 (r = kex_compose_ext_info_server(ssh, m)) != 0) 353 goto fail; 354 if (ssh->kex->ext_info_s && 355 (r = kex_compose_ext_info_client(ssh, m)) != 0) 356 goto fail; 357 358 /* Send the actual KEX_INFO packet */ 359 debug("Sending SSH2_MSG_EXT_INFO"); 360 if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || 361 (r = sshpkt_putb(ssh, m)) != 0 || 362 (r = sshpkt_send(ssh)) != 0) { 363 error_f("send EXT_INFO"); 364 goto fail; 365 } 366 367 r = 0; 368 369 fail: 370 sshbuf_free(m); 371 return r; 372 } 373 374 int 375 kex_server_update_ext_info(struct ssh *ssh) 376 { 377 int r; 378 379 if ((ssh->kex->flags & KEX_HAS_EXT_INFO_IN_AUTH) == 0) 380 return 0; 381 382 debug_f("Sending SSH2_MSG_EXT_INFO"); 383 if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || 384 (r = sshpkt_put_u32(ssh, 1)) != 0 || 385 (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || 386 (r = sshpkt_put_cstring(ssh, ssh->kex->server_sig_algs)) != 0 || 387 (r = sshpkt_send(ssh)) != 0) { 388 error_f("send EXT_INFO"); 389 return r; 390 } 391 return 0; 392 } 393 394 int 395 kex_send_newkeys(struct ssh *ssh) 396 { 397 int r; 398 399 kex_reset_dispatch(ssh); 400 if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 || 401 (r = sshpkt_send(ssh)) != 0) 402 return r; 403 debug("SSH2_MSG_NEWKEYS sent"); 404 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); 405 if ((r = kex_maybe_send_ext_info(ssh)) != 0) 406 return r; 407 debug("expecting SSH2_MSG_NEWKEYS"); 408 return 0; 409 } 410 411 /* Check whether an ext_info value contains the expected version string */ 412 static int 413 kex_ext_info_check_ver(struct kex *kex, const char *name, 414 const u_char *val, size_t len, const char *want_ver, u_int flag) 415 { 416 if (memchr(val, '\0', len) != NULL) { 417 error("SSH2_MSG_EXT_INFO: %s value contains nul byte", name); 418 return SSH_ERR_INVALID_FORMAT; 419 } 420 debug_f("%s=<%s>", name, val); 421 if (strcmp((const char *)val, want_ver) == 0) 422 kex->flags |= flag; 423 else 424 debug_f("unsupported version of %s extension", name); 425 return 0; 426 } 427 428 static int 429 kex_ext_info_client_parse(struct ssh *ssh, const char *name, 430 const u_char *value, size_t vlen) 431 { 432 int r; 433 434 /* NB. some messages are only accepted in the initial EXT_INFO */ 435 if (strcmp(name, "server-sig-algs") == 0) { 436 /* Ensure no \0 lurking in value */ 437 if (memchr(value, '\0', vlen) != NULL) { 438 error_f("nul byte in %s", name); 439 return SSH_ERR_INVALID_FORMAT; 440 } 441 debug_f("%s=<%s>", name, value); 442 free(ssh->kex->server_sig_algs); 443 ssh->kex->server_sig_algs = xstrdup((const char *)value); 444 } else if (ssh->kex->ext_info_received == 1 && 445 strcmp(name, "publickey-hostbound@openssh.com") == 0) { 446 if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen, 447 "0", KEX_HAS_PUBKEY_HOSTBOUND)) != 0) { 448 return r; 449 } 450 } else if (ssh->kex->ext_info_received == 1 && 451 strcmp(name, "ping@openssh.com") == 0) { 452 if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen, 453 "0", KEX_HAS_PING)) != 0) { 454 return r; 455 } 456 } else 457 debug_f("%s (unrecognised)", name); 458 459 return 0; 460 } 461 462 static int 463 kex_ext_info_server_parse(struct ssh *ssh, const char *name, 464 const u_char *value, size_t vlen) 465 { 466 int r; 467 468 if (strcmp(name, "ext-info-in-auth@openssh.com") == 0) { 469 if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen, 470 "0", KEX_HAS_EXT_INFO_IN_AUTH)) != 0) { 471 return r; 472 } 473 } else 474 debug_f("%s (unrecognised)", name); 475 return 0; 476 } 477 478 int 479 kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) 480 { 481 struct kex *kex = ssh->kex; 482 const int max_ext_info = kex->server ? 1 : 2; 483 u_int32_t i, ninfo; 484 char *name; 485 u_char *val; 486 size_t vlen; 487 int r; 488 489 debug("SSH2_MSG_EXT_INFO received"); 490 if (++kex->ext_info_received > max_ext_info) { 491 error("too many SSH2_MSG_EXT_INFO messages sent by peer"); 492 return dispatch_protocol_error(type, seq, ssh); 493 } 494 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error); 495 if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0) 496 return r; 497 if (ninfo >= 1024) { 498 error("SSH2_MSG_EXT_INFO with too many entries, expected " 499 "<=1024, received %u", ninfo); 500 return dispatch_protocol_error(type, seq, ssh); 501 } 502 for (i = 0; i < ninfo; i++) { 503 if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) 504 return r; 505 if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) { 506 free(name); 507 return r; 508 } 509 debug3_f("extension %s", name); 510 if (kex->server) { 511 if ((r = kex_ext_info_server_parse(ssh, name, 512 val, vlen)) != 0) 513 return r; 514 } else { 515 if ((r = kex_ext_info_client_parse(ssh, name, 516 val, vlen)) != 0) 517 return r; 518 } 519 free(name); 520 free(val); 521 } 522 return sshpkt_get_end(ssh); 523 } 524 525 static int 526 kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) 527 { 528 struct kex *kex = ssh->kex; 529 int r, initial = (kex->flags & KEX_INITIAL) != 0; 530 char *cp, **prop; 531 532 debug("SSH2_MSG_NEWKEYS received"); 533 if (kex->ext_info_c && initial) 534 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_input_ext_info); 535 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); 536 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); 537 if ((r = sshpkt_get_end(ssh)) != 0) 538 return r; 539 if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0) 540 return r; 541 if (initial) { 542 /* Remove initial KEX signalling from proposal for rekeying */ 543 if ((r = kex_buf2prop(kex->my, NULL, &prop)) != 0) 544 return r; 545 if ((cp = match_filter_denylist(prop[PROPOSAL_KEX_ALGS], 546 kex->server ? 547 "ext-info-s,kex-strict-s-v00@openssh.com" : 548 "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL) { 549 error_f("match_filter_denylist failed"); 550 goto fail; 551 } 552 free(prop[PROPOSAL_KEX_ALGS]); 553 prop[PROPOSAL_KEX_ALGS] = cp; 554 if ((r = kex_prop2buf(ssh->kex->my, prop)) != 0) { 555 error_f("kex_prop2buf failed"); 556 fail: 557 kex_proposal_free_entries(prop); 558 free(prop); 559 return SSH_ERR_INTERNAL_ERROR; 560 } 561 kex_proposal_free_entries(prop); 562 free(prop); 563 } 564 kex->done = 1; 565 kex->flags &= ~KEX_INITIAL; 566 sshbuf_reset(kex->peer); 567 kex->flags &= ~KEX_INIT_SENT; 568 free(kex->name); 569 kex->name = NULL; 570 return 0; 571 } 572 573 int 574 kex_send_kexinit(struct ssh *ssh) 575 { 576 u_char *cookie; 577 struct kex *kex = ssh->kex; 578 int r; 579 580 if (kex == NULL) { 581 error_f("no kex"); 582 return SSH_ERR_INTERNAL_ERROR; 583 } 584 if (kex->flags & KEX_INIT_SENT) 585 return 0; 586 kex->done = 0; 587 588 /* generate a random cookie */ 589 if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) { 590 error_f("bad kex length: %zu < %d", 591 sshbuf_len(kex->my), KEX_COOKIE_LEN); 592 return SSH_ERR_INVALID_FORMAT; 593 } 594 if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) { 595 error_f("buffer error"); 596 return SSH_ERR_INTERNAL_ERROR; 597 } 598 arc4random_buf(cookie, KEX_COOKIE_LEN); 599 600 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 || 601 (r = sshpkt_putb(ssh, kex->my)) != 0 || 602 (r = sshpkt_send(ssh)) != 0) { 603 error_fr(r, "compose reply"); 604 return r; 605 } 606 debug("SSH2_MSG_KEXINIT sent"); 607 kex->flags |= KEX_INIT_SENT; 608 return 0; 609 } 610 611 int 612 kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) 613 { 614 struct kex *kex = ssh->kex; 615 const u_char *ptr; 616 u_int i; 617 size_t dlen; 618 int r; 619 620 debug("SSH2_MSG_KEXINIT received"); 621 if (kex == NULL) { 622 error_f("no kex"); 623 return SSH_ERR_INTERNAL_ERROR; 624 } 625 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error); 626 ptr = sshpkt_ptr(ssh, &dlen); 627 if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) 628 return r; 629 630 /* discard packet */ 631 for (i = 0; i < KEX_COOKIE_LEN; i++) { 632 if ((r = sshpkt_get_u8(ssh, NULL)) != 0) { 633 error_fr(r, "discard cookie"); 634 return r; 635 } 636 } 637 for (i = 0; i < PROPOSAL_MAX; i++) { 638 if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { 639 error_fr(r, "discard proposal"); 640 return r; 641 } 642 } 643 /* 644 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported 645 * KEX method has the server move first, but a server might be using 646 * a custom method or one that we otherwise don't support. We should 647 * be prepared to remember first_kex_follows here so we can eat a 648 * packet later. 649 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means 650 * for cases where the server *doesn't* go first. I guess we should 651 * ignore it when it is set for these cases, which is what we do now. 652 */ 653 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */ 654 (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */ 655 (r = sshpkt_get_end(ssh)) != 0) 656 return r; 657 658 if (!(kex->flags & KEX_INIT_SENT)) 659 if ((r = kex_send_kexinit(ssh)) != 0) 660 return r; 661 if ((r = kex_choose_conf(ssh, seq)) != 0) 662 return r; 663 664 if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL) 665 return (kex->kex[kex->kex_type])(ssh); 666 667 error_f("unknown kex type %u", kex->kex_type); 668 return SSH_ERR_INTERNAL_ERROR; 669 } 670 671 struct kex * 672 kex_new(void) 673 { 674 struct kex *kex; 675 676 if ((kex = calloc(1, sizeof(*kex))) == NULL || 677 (kex->peer = sshbuf_new()) == NULL || 678 (kex->my = sshbuf_new()) == NULL || 679 (kex->client_version = sshbuf_new()) == NULL || 680 (kex->server_version = sshbuf_new()) == NULL || 681 (kex->session_id = sshbuf_new()) == NULL) { 682 kex_free(kex); 683 return NULL; 684 } 685 return kex; 686 } 687 688 void 689 kex_free_newkeys(struct newkeys *newkeys) 690 { 691 if (newkeys == NULL) 692 return; 693 if (newkeys->enc.key) { 694 explicit_bzero(newkeys->enc.key, newkeys->enc.key_len); 695 free(newkeys->enc.key); 696 newkeys->enc.key = NULL; 697 } 698 if (newkeys->enc.iv) { 699 explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len); 700 free(newkeys->enc.iv); 701 newkeys->enc.iv = NULL; 702 } 703 free(newkeys->enc.name); 704 explicit_bzero(&newkeys->enc, sizeof(newkeys->enc)); 705 free(newkeys->comp.name); 706 explicit_bzero(&newkeys->comp, sizeof(newkeys->comp)); 707 mac_clear(&newkeys->mac); 708 if (newkeys->mac.key) { 709 explicit_bzero(newkeys->mac.key, newkeys->mac.key_len); 710 free(newkeys->mac.key); 711 newkeys->mac.key = NULL; 712 } 713 free(newkeys->mac.name); 714 explicit_bzero(&newkeys->mac, sizeof(newkeys->mac)); 715 freezero(newkeys, sizeof(*newkeys)); 716 } 717 718 void 719 kex_free(struct kex *kex) 720 { 721 u_int mode; 722 723 if (kex == NULL) 724 return; 725 726 #ifdef WITH_OPENSSL 727 DH_free(kex->dh); 728 EC_KEY_free(kex->ec_client_key); 729 #endif 730 for (mode = 0; mode < MODE_MAX; mode++) { 731 kex_free_newkeys(kex->newkeys[mode]); 732 kex->newkeys[mode] = NULL; 733 } 734 sshbuf_free(kex->peer); 735 sshbuf_free(kex->my); 736 sshbuf_free(kex->client_version); 737 sshbuf_free(kex->server_version); 738 sshbuf_free(kex->client_pub); 739 sshbuf_free(kex->session_id); 740 sshbuf_free(kex->initial_sig); 741 sshkey_free(kex->initial_hostkey); 742 free(kex->failed_choice); 743 free(kex->hostkey_alg); 744 free(kex->name); 745 free(kex); 746 } 747 748 int 749 kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) 750 { 751 int r; 752 753 if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0) 754 return r; 755 ssh->kex->flags = KEX_INITIAL; 756 kex_reset_dispatch(ssh); 757 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); 758 return 0; 759 } 760 761 int 762 kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) 763 { 764 int r; 765 766 if ((r = kex_ready(ssh, proposal)) != 0) 767 return r; 768 if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */ 769 kex_free(ssh->kex); 770 ssh->kex = NULL; 771 return r; 772 } 773 return 0; 774 } 775 776 /* 777 * Request key re-exchange, returns 0 on success or a ssherr.h error 778 * code otherwise. Must not be called if KEX is incomplete or in-progress. 779 */ 780 int 781 kex_start_rekex(struct ssh *ssh) 782 { 783 if (ssh->kex == NULL) { 784 error_f("no kex"); 785 return SSH_ERR_INTERNAL_ERROR; 786 } 787 if (ssh->kex->done == 0) { 788 error_f("requested twice"); 789 return SSH_ERR_INTERNAL_ERROR; 790 } 791 ssh->kex->done = 0; 792 return kex_send_kexinit(ssh); 793 } 794 795 static int 796 choose_enc(struct sshenc *enc, char *client, char *server) 797 { 798 char *name = match_list(client, server, NULL); 799 800 if (name == NULL) 801 return SSH_ERR_NO_CIPHER_ALG_MATCH; 802 if ((enc->cipher = cipher_by_name(name)) == NULL) { 803 error_f("unsupported cipher %s", name); 804 free(name); 805 return SSH_ERR_INTERNAL_ERROR; 806 } 807 enc->name = name; 808 enc->enabled = 0; 809 enc->iv = NULL; 810 enc->iv_len = cipher_ivlen(enc->cipher); 811 enc->key = NULL; 812 enc->key_len = cipher_keylen(enc->cipher); 813 enc->block_size = cipher_blocksize(enc->cipher); 814 return 0; 815 } 816 817 static int 818 choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) 819 { 820 char *name = match_list(client, server, NULL); 821 822 if (name == NULL) 823 return SSH_ERR_NO_MAC_ALG_MATCH; 824 if (mac_setup(mac, name) < 0) { 825 error_f("unsupported MAC %s", name); 826 free(name); 827 return SSH_ERR_INTERNAL_ERROR; 828 } 829 mac->name = name; 830 mac->key = NULL; 831 mac->enabled = 0; 832 return 0; 833 } 834 835 static int 836 choose_comp(struct sshcomp *comp, char *client, char *server) 837 { 838 char *name = match_list(client, server, NULL); 839 840 if (name == NULL) 841 return SSH_ERR_NO_COMPRESS_ALG_MATCH; 842 #ifdef WITH_ZLIB 843 if (strcmp(name, "zlib@openssh.com") == 0) { 844 comp->type = COMP_DELAYED; 845 } else if (strcmp(name, "zlib") == 0) { 846 comp->type = COMP_ZLIB; 847 } else 848 #endif /* WITH_ZLIB */ 849 if (strcmp(name, "none") == 0) { 850 comp->type = COMP_NONE; 851 } else { 852 error_f("unsupported compression scheme %s", name); 853 free(name); 854 return SSH_ERR_INTERNAL_ERROR; 855 } 856 comp->name = name; 857 return 0; 858 } 859 860 static int 861 choose_kex(struct kex *k, char *client, char *server) 862 { 863 k->name = match_list(client, server, NULL); 864 865 debug("kex: algorithm: %s", k->name ? k->name : "(no match)"); 866 if (k->name == NULL) 867 return SSH_ERR_NO_KEX_ALG_MATCH; 868 if (!kex_name_valid(k->name)) { 869 error_f("unsupported KEX method %s", k->name); 870 return SSH_ERR_INTERNAL_ERROR; 871 } 872 k->kex_type = kex_type_from_name(k->name); 873 k->hash_alg = kex_hash_from_name(k->name); 874 k->ec_nid = kex_nid_from_name(k->name); 875 return 0; 876 } 877 878 static int 879 choose_hostkeyalg(struct kex *k, char *client, char *server) 880 { 881 free(k->hostkey_alg); 882 k->hostkey_alg = match_list(client, server, NULL); 883 884 debug("kex: host key algorithm: %s", 885 k->hostkey_alg ? k->hostkey_alg : "(no match)"); 886 if (k->hostkey_alg == NULL) 887 return SSH_ERR_NO_HOSTKEY_ALG_MATCH; 888 k->hostkey_type = sshkey_type_from_name(k->hostkey_alg); 889 if (k->hostkey_type == KEY_UNSPEC) { 890 error_f("unsupported hostkey algorithm %s", k->hostkey_alg); 891 return SSH_ERR_INTERNAL_ERROR; 892 } 893 k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg); 894 return 0; 895 } 896 897 static int 898 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) 899 { 900 static int check[] = { 901 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1 902 }; 903 int *idx; 904 char *p; 905 906 for (idx = &check[0]; *idx != -1; idx++) { 907 if ((p = strchr(my[*idx], ',')) != NULL) 908 *p = '\0'; 909 if ((p = strchr(peer[*idx], ',')) != NULL) 910 *p = '\0'; 911 if (strcmp(my[*idx], peer[*idx]) != 0) { 912 debug2("proposal mismatch: my %s peer %s", 913 my[*idx], peer[*idx]); 914 return (0); 915 } 916 } 917 debug2("proposals match"); 918 return (1); 919 } 920 921 static int 922 kexalgs_contains(char **peer, const char *ext) 923 { 924 return kex_has_any_alg(peer[PROPOSAL_KEX_ALGS], ext); 925 } 926 927 static int 928 kex_choose_conf(struct ssh *ssh, uint32_t seq) 929 { 930 struct kex *kex = ssh->kex; 931 struct newkeys *newkeys; 932 char **my = NULL, **peer = NULL; 933 char **cprop, **sprop; 934 int nenc, nmac, ncomp; 935 u_int mode, ctos, need, dh_need, authlen; 936 int log_flag = 0; 937 int r, first_kex_follows; 938 939 debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); 940 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) 941 goto out; 942 debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server"); 943 if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) 944 goto out; 945 946 if (kex->server) { 947 cprop=peer; 948 sprop=my; 949 } else { 950 cprop=my; 951 sprop=peer; 952 } 953 954 /* Check whether peer supports ext_info/kex_strict */ 955 if ((kex->flags & KEX_INITIAL) != 0) { 956 if (kex->server) { 957 kex->ext_info_c = kexalgs_contains(peer, "ext-info-c"); 958 kex->kex_strict = kexalgs_contains(peer, 959 "kex-strict-c-v00@openssh.com"); 960 } else { 961 kex->ext_info_s = kexalgs_contains(peer, "ext-info-s"); 962 kex->kex_strict = kexalgs_contains(peer, 963 "kex-strict-s-v00@openssh.com"); 964 } 965 if (kex->kex_strict) { 966 debug3_f("will use strict KEX ordering"); 967 if (seq != 0) 968 ssh_packet_disconnect(ssh, 969 "strict KEX violation: " 970 "KEXINIT was not the first packet"); 971 } 972 } 973 974 /* Check whether client supports rsa-sha2 algorithms */ 975 if (kex->server && (kex->flags & KEX_INITIAL)) { 976 if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], 977 "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com")) 978 kex->flags |= KEX_RSA_SHA2_256_SUPPORTED; 979 if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], 980 "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com")) 981 kex->flags |= KEX_RSA_SHA2_512_SUPPORTED; 982 } 983 984 /* Algorithm Negotiation */ 985 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], 986 sprop[PROPOSAL_KEX_ALGS])) != 0) { 987 kex->failed_choice = peer[PROPOSAL_KEX_ALGS]; 988 peer[PROPOSAL_KEX_ALGS] = NULL; 989 goto out; 990 } 991 if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 992 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) { 993 kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS]; 994 peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL; 995 goto out; 996 } 997 for (mode = 0; mode < MODE_MAX; mode++) { 998 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) { 999 r = SSH_ERR_ALLOC_FAIL; 1000 goto out; 1001 } 1002 kex->newkeys[mode] = newkeys; 1003 ctos = (!kex->server && mode == MODE_OUT) || 1004 (kex->server && mode == MODE_IN); 1005 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; 1006 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; 1007 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; 1008 if ((r = choose_enc(&newkeys->enc, cprop[nenc], 1009 sprop[nenc])) != 0) { 1010 kex->failed_choice = peer[nenc]; 1011 peer[nenc] = NULL; 1012 goto out; 1013 } 1014 authlen = cipher_authlen(newkeys->enc.cipher); 1015 /* ignore mac for authenticated encryption */ 1016 if (authlen == 0 && 1017 (r = choose_mac(ssh, &newkeys->mac, cprop[nmac], 1018 sprop[nmac])) != 0) { 1019 kex->failed_choice = peer[nmac]; 1020 peer[nmac] = NULL; 1021 goto out; 1022 } 1023 if ((r = choose_comp(&newkeys->comp, cprop[ncomp], 1024 sprop[ncomp])) != 0) { 1025 kex->failed_choice = peer[ncomp]; 1026 peer[ncomp] = NULL; 1027 goto out; 1028 } 1029 debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); 1030 if (strcmp(newkeys->enc.name, "none") == 0) { 1031 int auth_flag; 1032 1033 auth_flag = ssh_packet_authentication_state(ssh); 1034 debug("Requesting NONE. Authflag is %d", auth_flag); 1035 if (auth_flag == 1) { 1036 debug("None requested post authentication."); 1037 } else { 1038 fatal("Pre-authentication none cipher requests are not allowed."); 1039 } 1040 } 1041 debug("kex: %s cipher: %s MAC: %s compression: %s", 1042 ctos ? "client->server" : "server->client", 1043 newkeys->enc.name, 1044 authlen == 0 ? newkeys->mac.name : "<implicit>", 1045 newkeys->comp.name); 1046 /* client starts withctos = 0 && log flag = 0 and no log*/ 1047 /* 2nd client pass ctos=1 and flag = 1 so no log*/ 1048 /* server starts with ctos =1 && log_flag = 0 so log */ 1049 /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/ 1050 /* -cjr*/ 1051 if (ctos && !log_flag) { 1052 logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s", 1053 ssh_remote_ipaddr(ssh), 1054 ssh_remote_port(ssh), 1055 newkeys->enc.name, 1056 newkeys->mac.name, 1057 newkeys->comp.name); 1058 } 1059 log_flag = 1; 1060 } 1061 need = dh_need = 0; 1062 for (mode = 0; mode < MODE_MAX; mode++) { 1063 newkeys = kex->newkeys[mode]; 1064 need = MAXIMUM(need, newkeys->enc.key_len); 1065 need = MAXIMUM(need, newkeys->enc.block_size); 1066 need = MAXIMUM(need, newkeys->enc.iv_len); 1067 need = MAXIMUM(need, newkeys->mac.key_len); 1068 dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher)); 1069 dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); 1070 dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); 1071 dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); 1072 } 1073 /* XXX need runden? */ 1074 kex->we_need = need; 1075 kex->dh_need = dh_need; 1076 1077 /* ignore the next message if the proposals do not match */ 1078 if (first_kex_follows && !proposals_match(my, peer)) 1079 ssh->dispatch_skip_packets = 1; 1080 r = 0; 1081 out: 1082 kex_prop_free(my); 1083 kex_prop_free(peer); 1084 return r; 1085 } 1086 1087 static int 1088 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, 1089 const struct sshbuf *shared_secret, u_char **keyp) 1090 { 1091 struct kex *kex = ssh->kex; 1092 struct ssh_digest_ctx *hashctx = NULL; 1093 char c = id; 1094 u_int have; 1095 size_t mdsz; 1096 u_char *digest; 1097 int r; 1098 1099 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) 1100 return SSH_ERR_INVALID_ARGUMENT; 1101 if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) { 1102 r = SSH_ERR_ALLOC_FAIL; 1103 goto out; 1104 } 1105 1106 /* K1 = HASH(K || H || "A" || session_id) */ 1107 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || 1108 ssh_digest_update_buffer(hashctx, shared_secret) != 0 || 1109 ssh_digest_update(hashctx, hash, hashlen) != 0 || 1110 ssh_digest_update(hashctx, &c, 1) != 0 || 1111 ssh_digest_update_buffer(hashctx, kex->session_id) != 0 || 1112 ssh_digest_final(hashctx, digest, mdsz) != 0) { 1113 r = SSH_ERR_LIBCRYPTO_ERROR; 1114 error_f("KEX hash failed"); 1115 goto out; 1116 } 1117 ssh_digest_free(hashctx); 1118 hashctx = NULL; 1119 1120 /* 1121 * expand key: 1122 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1) 1123 * Key = K1 || K2 || ... || Kn 1124 */ 1125 for (have = mdsz; need > have; have += mdsz) { 1126 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || 1127 ssh_digest_update_buffer(hashctx, shared_secret) != 0 || 1128 ssh_digest_update(hashctx, hash, hashlen) != 0 || 1129 ssh_digest_update(hashctx, digest, have) != 0 || 1130 ssh_digest_final(hashctx, digest + have, mdsz) != 0) { 1131 error_f("KDF failed"); 1132 r = SSH_ERR_LIBCRYPTO_ERROR; 1133 goto out; 1134 } 1135 ssh_digest_free(hashctx); 1136 hashctx = NULL; 1137 } 1138 #ifdef DEBUG_KEX 1139 fprintf(stderr, "key '%c'== ", c); 1140 dump_digest("key", digest, need); 1141 #endif 1142 *keyp = digest; 1143 digest = NULL; 1144 r = 0; 1145 out: 1146 free(digest); 1147 ssh_digest_free(hashctx); 1148 return r; 1149 } 1150 1151 #define NKEYS 6 1152 int 1153 kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen, 1154 const struct sshbuf *shared_secret) 1155 { 1156 struct kex *kex = ssh->kex; 1157 u_char *keys[NKEYS]; 1158 u_int i, j, mode, ctos; 1159 int r; 1160 1161 /* save initial hash as session id */ 1162 if ((kex->flags & KEX_INITIAL) != 0) { 1163 if (sshbuf_len(kex->session_id) != 0) { 1164 error_f("already have session ID at kex"); 1165 return SSH_ERR_INTERNAL_ERROR; 1166 } 1167 if ((r = sshbuf_put(kex->session_id, hash, hashlen)) != 0) 1168 return r; 1169 } else if (sshbuf_len(kex->session_id) == 0) { 1170 error_f("no session ID in rekex"); 1171 return SSH_ERR_INTERNAL_ERROR; 1172 } 1173 for (i = 0; i < NKEYS; i++) { 1174 if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen, 1175 shared_secret, &keys[i])) != 0) { 1176 for (j = 0; j < i; j++) 1177 free(keys[j]); 1178 return r; 1179 } 1180 } 1181 for (mode = 0; mode < MODE_MAX; mode++) { 1182 ctos = (!kex->server && mode == MODE_OUT) || 1183 (kex->server && mode == MODE_IN); 1184 kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1]; 1185 kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3]; 1186 kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5]; 1187 } 1188 return 0; 1189 } 1190 1191 int 1192 kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp) 1193 { 1194 struct kex *kex = ssh->kex; 1195 1196 *pubp = NULL; 1197 *prvp = NULL; 1198 if (kex->load_host_public_key == NULL || 1199 kex->load_host_private_key == NULL) { 1200 error_f("missing hostkey loader"); 1201 return SSH_ERR_INVALID_ARGUMENT; 1202 } 1203 *pubp = kex->load_host_public_key(kex->hostkey_type, 1204 kex->hostkey_nid, ssh); 1205 *prvp = kex->load_host_private_key(kex->hostkey_type, 1206 kex->hostkey_nid, ssh); 1207 if (*pubp == NULL) 1208 return SSH_ERR_NO_HOSTKEY_LOADED; 1209 return 0; 1210 } 1211 1212 int 1213 kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key) 1214 { 1215 struct kex *kex = ssh->kex; 1216 1217 if (kex->verify_host_key == NULL) { 1218 error_f("missing hostkey verifier"); 1219 return SSH_ERR_INVALID_ARGUMENT; 1220 } 1221 if (server_host_key->type != kex->hostkey_type || 1222 (kex->hostkey_type == KEY_ECDSA && 1223 server_host_key->ecdsa_nid != kex->hostkey_nid)) 1224 return SSH_ERR_KEY_TYPE_MISMATCH; 1225 if (kex->verify_host_key(server_host_key, ssh) == -1) 1226 return SSH_ERR_SIGNATURE_INVALID; 1227 return 0; 1228 } 1229 1230 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 1231 void 1232 dump_digest(const char *msg, const u_char *digest, int len) 1233 { 1234 fprintf(stderr, "%s\n", msg); 1235 sshbuf_dump_data(digest, len, stderr); 1236 } 1237 #endif 1238 1239 /* 1240 * Send a plaintext error message to the peer, suffixed by \r\n. 1241 * Only used during banner exchange, and there only for the server. 1242 */ 1243 static void 1244 send_error(struct ssh *ssh, const char *msg) 1245 { 1246 const char *crnl = "\r\n"; 1247 1248 if (!ssh->kex->server) 1249 return; 1250 1251 if (atomicio(vwrite, ssh_packet_get_connection_out(ssh), 1252 __UNCONST(msg), strlen(msg)) != strlen(msg) || 1253 atomicio(vwrite, ssh_packet_get_connection_out(ssh), 1254 __UNCONST(crnl), strlen(crnl)) != strlen(crnl)) 1255 error_f("write: %.100s", strerror(errno)); 1256 } 1257 1258 /* 1259 * Sends our identification string and waits for the peer's. Will block for 1260 * up to timeout_ms (or indefinitely if timeout_ms <= 0). 1261 * Returns on 0 success or a ssherr.h code on failure. 1262 */ 1263 int 1264 kex_exchange_identification(struct ssh *ssh, int timeout_ms, 1265 const char *version_addendum) 1266 { 1267 int remote_major, remote_minor, mismatch, oerrno = 0; 1268 size_t len, n; 1269 int r, expect_nl; 1270 u_char c; 1271 struct sshbuf *our_version = ssh->kex->server ? 1272 ssh->kex->server_version : ssh->kex->client_version; 1273 struct sshbuf *peer_version = ssh->kex->server ? 1274 ssh->kex->client_version : ssh->kex->server_version; 1275 char *our_version_string = NULL, *peer_version_string = NULL; 1276 char *cp, *remote_version = NULL; 1277 1278 /* Prepare and send our banner */ 1279 sshbuf_reset(our_version); 1280 if (version_addendum != NULL && *version_addendum == '\0') 1281 version_addendum = NULL; 1282 if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n", 1283 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, 1284 version_addendum == NULL ? "" : " ", 1285 version_addendum == NULL ? "" : version_addendum)) != 0) { 1286 oerrno = errno; 1287 error_fr(r, "sshbuf_putf"); 1288 goto out; 1289 } 1290 1291 if (atomicio(vwrite, ssh_packet_get_connection_out(ssh), 1292 sshbuf_mutable_ptr(our_version), 1293 sshbuf_len(our_version)) != sshbuf_len(our_version)) { 1294 oerrno = errno; 1295 debug_f("write: %.100s", strerror(errno)); 1296 r = SSH_ERR_SYSTEM_ERROR; 1297 goto out; 1298 } 1299 if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */ 1300 oerrno = errno; 1301 error_fr(r, "sshbuf_consume_end"); 1302 goto out; 1303 } 1304 our_version_string = sshbuf_dup_string(our_version); 1305 if (our_version_string == NULL) { 1306 error_f("sshbuf_dup_string failed"); 1307 r = SSH_ERR_ALLOC_FAIL; 1308 goto out; 1309 } 1310 debug("Local version string %.100s", our_version_string); 1311 1312 /* Read other side's version identification. */ 1313 for (n = 0; ; n++) { 1314 if (n >= SSH_MAX_PRE_BANNER_LINES) { 1315 send_error(ssh, "No SSH identification string " 1316 "received."); 1317 error_f("No SSH version received in first %u lines " 1318 "from server", SSH_MAX_PRE_BANNER_LINES); 1319 r = SSH_ERR_INVALID_FORMAT; 1320 goto out; 1321 } 1322 sshbuf_reset(peer_version); 1323 expect_nl = 0; 1324 for (;;) { 1325 if (timeout_ms > 0) { 1326 r = waitrfd(ssh_packet_get_connection_in(ssh), 1327 &timeout_ms, NULL); 1328 if (r == -1 && errno == ETIMEDOUT) { 1329 send_error(ssh, "Timed out waiting " 1330 "for SSH identification string."); 1331 error("Connection timed out during " 1332 "banner exchange"); 1333 r = SSH_ERR_CONN_TIMEOUT; 1334 goto out; 1335 } else if (r == -1) { 1336 oerrno = errno; 1337 error_f("%s", strerror(errno)); 1338 r = SSH_ERR_SYSTEM_ERROR; 1339 goto out; 1340 } 1341 } 1342 1343 len = atomicio(read, ssh_packet_get_connection_in(ssh), 1344 &c, 1); 1345 if (len != 1 && errno == EPIPE) { 1346 verbose_f("Connection closed by remote host"); 1347 r = SSH_ERR_CONN_CLOSED; 1348 goto out; 1349 } else if (len != 1) { 1350 oerrno = errno; 1351 error_f("read: %.100s", strerror(errno)); 1352 r = SSH_ERR_SYSTEM_ERROR; 1353 goto out; 1354 } 1355 if (c == '\r') { 1356 expect_nl = 1; 1357 continue; 1358 } 1359 if (c == '\n') 1360 break; 1361 if (c == '\0' || expect_nl) { 1362 verbose_f("banner line contains invalid " 1363 "characters"); 1364 goto invalid; 1365 } 1366 if ((r = sshbuf_put_u8(peer_version, c)) != 0) { 1367 oerrno = errno; 1368 error_fr(r, "sshbuf_put"); 1369 goto out; 1370 } 1371 if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) { 1372 verbose_f("banner line too long"); 1373 goto invalid; 1374 } 1375 } 1376 /* Is this an actual protocol banner? */ 1377 if (sshbuf_len(peer_version) > 4 && 1378 memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0) 1379 break; 1380 /* If not, then just log the line and continue */ 1381 if ((cp = sshbuf_dup_string(peer_version)) == NULL) { 1382 error_f("sshbuf_dup_string failed"); 1383 r = SSH_ERR_ALLOC_FAIL; 1384 goto out; 1385 } 1386 /* Do not accept lines before the SSH ident from a client */ 1387 if (ssh->kex->server) { 1388 verbose_f("client sent invalid protocol identifier " 1389 "\"%.256s\"", cp); 1390 free(cp); 1391 goto invalid; 1392 } 1393 debug_f("banner line %zu: %s", n, cp); 1394 free(cp); 1395 } 1396 peer_version_string = sshbuf_dup_string(peer_version); 1397 if (peer_version_string == NULL) 1398 fatal_f("sshbuf_dup_string failed"); 1399 /* XXX must be same size for sscanf */ 1400 if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) { 1401 error_f("calloc failed"); 1402 r = SSH_ERR_ALLOC_FAIL; 1403 goto out; 1404 } 1405 1406 /* 1407 * Check that the versions match. In future this might accept 1408 * several versions and set appropriate flags to handle them. 1409 */ 1410 if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n", 1411 &remote_major, &remote_minor, remote_version) != 3) { 1412 error("Bad remote protocol version identification: '%.100s'", 1413 peer_version_string); 1414 invalid: 1415 send_error(ssh, "Invalid SSH identification string."); 1416 r = SSH_ERR_INVALID_FORMAT; 1417 goto out; 1418 } 1419 debug("Remote protocol version %d.%d, remote software version %.100s", 1420 remote_major, remote_minor, remote_version); 1421 compat_banner(ssh, remote_version); 1422 1423 mismatch = 0; 1424 switch (remote_major) { 1425 case 2: 1426 break; 1427 case 1: 1428 if (remote_minor != 99) 1429 mismatch = 1; 1430 break; 1431 default: 1432 mismatch = 1; 1433 break; 1434 } 1435 if (mismatch) { 1436 error("Protocol major versions differ: %d vs. %d", 1437 PROTOCOL_MAJOR_2, remote_major); 1438 send_error(ssh, "Protocol major versions differ."); 1439 r = SSH_ERR_NO_PROTOCOL_VERSION; 1440 goto out; 1441 } 1442 1443 if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) { 1444 logit("probed from %s port %d with %s. Don't panic.", 1445 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 1446 peer_version_string); 1447 r = SSH_ERR_CONN_CLOSED; /* XXX */ 1448 goto out; 1449 } 1450 if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) { 1451 logit("scanned from %s port %d with %s. Don't panic.", 1452 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 1453 peer_version_string); 1454 r = SSH_ERR_CONN_CLOSED; /* XXX */ 1455 goto out; 1456 } 1457 /* success */ 1458 r = 0; 1459 out: 1460 free(our_version_string); 1461 free(peer_version_string); 1462 free(remote_version); 1463 if (r == SSH_ERR_SYSTEM_ERROR) 1464 errno = oerrno; 1465 return r; 1466 } 1467 1468