kex.c revision 1.137
1/* $OpenBSD: kex.c,v 1.137 2018/07/03 11:39:54 djm Exp $ */ 2/* 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 27#include <signal.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31 32#ifdef WITH_OPENSSL 33#include <openssl/crypto.h> 34#endif 35 36#include "ssh2.h" 37#include "packet.h" 38#include "compat.h" 39#include "cipher.h" 40#include "sshkey.h" 41#include "kex.h" 42#include "log.h" 43#include "mac.h" 44#include "match.h" 45#include "misc.h" 46#include "dispatch.h" 47#include "monitor.h" 48 49#include "ssherr.h" 50#include "sshbuf.h" 51#include "digest.h" 52 53/* prototype */ 54static int kex_choose_conf(struct ssh *); 55static int kex_input_newkeys(int, u_int32_t, struct ssh *); 56 57static const char *proposal_names[PROPOSAL_MAX] = { 58 "KEX algorithms", 59 "host key algorithms", 60 "ciphers ctos", 61 "ciphers stoc", 62 "MACs ctos", 63 "MACs stoc", 64 "compression ctos", 65 "compression stoc", 66 "languages ctos", 67 "languages stoc", 68}; 69 70struct kexalg { 71 char *name; 72 u_int type; 73 int ec_nid; 74 int hash_alg; 75}; 76static const struct kexalg kexalgs[] = { 77#ifdef WITH_OPENSSL 78 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, 79 { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, 80 { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, 81 { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, 82 { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, 83 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, 84 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, 85 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, 86 NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, 87 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, 88 SSH_DIGEST_SHA384 }, 89 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, 90 SSH_DIGEST_SHA512 }, 91#endif 92 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, 93 { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, 94 { NULL, -1, -1, -1}, 95}; 96 97char * 98kex_alg_list(char sep) 99{ 100 char *ret = NULL, *tmp; 101 size_t nlen, rlen = 0; 102 const struct kexalg *k; 103 104 for (k = kexalgs; k->name != NULL; k++) { 105 if (ret != NULL) 106 ret[rlen++] = sep; 107 nlen = strlen(k->name); 108 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { 109 free(ret); 110 return NULL; 111 } 112 ret = tmp; 113 memcpy(ret + rlen, k->name, nlen + 1); 114 rlen += nlen; 115 } 116 return ret; 117} 118 119static const struct kexalg * 120kex_alg_by_name(const char *name) 121{ 122 const struct kexalg *k; 123 124 for (k = kexalgs; k->name != NULL; k++) { 125 if (strcmp(k->name, name) == 0) 126 return k; 127 } 128 return NULL; 129} 130 131/* Validate KEX method name list */ 132int 133kex_names_valid(const char *names) 134{ 135 char *s, *cp, *p; 136 137 if (names == NULL || strcmp(names, "") == 0) 138 return 0; 139 if ((s = cp = strdup(names)) == NULL) 140 return 0; 141 for ((p = strsep(&cp, ",")); p && *p != '\0'; 142 (p = strsep(&cp, ","))) { 143 if (kex_alg_by_name(p) == NULL) { 144 error("Unsupported KEX algorithm \"%.100s\"", p); 145 free(s); 146 return 0; 147 } 148 } 149 debug3("kex names ok: [%s]", names); 150 free(s); 151 return 1; 152} 153 154/* 155 * Concatenate algorithm names, avoiding duplicates in the process. 156 * Caller must free returned string. 157 */ 158char * 159kex_names_cat(const char *a, const char *b) 160{ 161 char *ret = NULL, *tmp = NULL, *cp, *p, *m; 162 size_t len; 163 164 if (a == NULL || *a == '\0') 165 return NULL; 166 if (b == NULL || *b == '\0') 167 return strdup(a); 168 if (strlen(b) > 1024*1024) 169 return NULL; 170 len = strlen(a) + strlen(b) + 2; 171 if ((tmp = cp = strdup(b)) == NULL || 172 (ret = calloc(1, len)) == NULL) { 173 free(tmp); 174 return NULL; 175 } 176 strlcpy(ret, a, len); 177 for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { 178 if ((m = match_list(ret, p, NULL)) != NULL) { 179 free(m); 180 continue; /* Algorithm already present */ 181 } 182 if (strlcat(ret, ",", len) >= len || 183 strlcat(ret, p, len) >= len) { 184 free(tmp); 185 free(ret); 186 return NULL; /* Shouldn't happen */ 187 } 188 } 189 free(tmp); 190 return ret; 191} 192 193/* 194 * Assemble a list of algorithms from a default list and a string from a 195 * configuration file. The user-provided string may begin with '+' to 196 * indicate that it should be appended to the default or '-' that the 197 * specified names should be removed. 198 */ 199int 200kex_assemble_names(const char *def, char **list) 201{ 202 char *ret; 203 204 if (list == NULL || *list == NULL || **list == '\0') { 205 *list = strdup(def); 206 return 0; 207 } 208 if (**list == '+') { 209 if ((ret = kex_names_cat(def, *list + 1)) == NULL) 210 return SSH_ERR_ALLOC_FAIL; 211 free(*list); 212 *list = ret; 213 } else if (**list == '-') { 214 if ((ret = match_filter_list(def, *list + 1)) == NULL) 215 return SSH_ERR_ALLOC_FAIL; 216 free(*list); 217 *list = ret; 218 } 219 220 return 0; 221} 222 223/* put algorithm proposal into buffer */ 224int 225kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) 226{ 227 u_int i; 228 int r; 229 230 sshbuf_reset(b); 231 232 /* 233 * add a dummy cookie, the cookie will be overwritten by 234 * kex_send_kexinit(), each time a kexinit is set 235 */ 236 for (i = 0; i < KEX_COOKIE_LEN; i++) { 237 if ((r = sshbuf_put_u8(b, 0)) != 0) 238 return r; 239 } 240 for (i = 0; i < PROPOSAL_MAX; i++) { 241 if ((r = sshbuf_put_cstring(b, proposal[i])) != 0) 242 return r; 243 } 244 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */ 245 (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */ 246 return r; 247 return 0; 248} 249 250/* parse buffer and return algorithm proposal */ 251int 252kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp) 253{ 254 struct sshbuf *b = NULL; 255 u_char v; 256 u_int i; 257 char **proposal = NULL; 258 int r; 259 260 *propp = NULL; 261 if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL) 262 return SSH_ERR_ALLOC_FAIL; 263 if ((b = sshbuf_fromb(raw)) == NULL) { 264 r = SSH_ERR_ALLOC_FAIL; 265 goto out; 266 } 267 if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */ 268 goto out; 269 /* extract kex init proposal strings */ 270 for (i = 0; i < PROPOSAL_MAX; i++) { 271 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) 272 goto out; 273 debug2("%s: %s", proposal_names[i], proposal[i]); 274 } 275 /* first kex follows / reserved */ 276 if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */ 277 (r = sshbuf_get_u32(b, &i)) != 0) /* reserved */ 278 goto out; 279 if (first_kex_follows != NULL) 280 *first_kex_follows = v; 281 debug2("first_kex_follows %d ", v); 282 debug2("reserved %u ", i); 283 r = 0; 284 *propp = proposal; 285 out: 286 if (r != 0 && proposal != NULL) 287 kex_prop_free(proposal); 288 sshbuf_free(b); 289 return r; 290} 291 292void 293kex_prop_free(char **proposal) 294{ 295 u_int i; 296 297 if (proposal == NULL) 298 return; 299 for (i = 0; i < PROPOSAL_MAX; i++) 300 free(proposal[i]); 301 free(proposal); 302} 303 304/* ARGSUSED */ 305static int 306kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh) 307{ 308 int r; 309 310 error("kex protocol error: type %d seq %u", type, seq); 311 if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || 312 (r = sshpkt_put_u32(ssh, seq)) != 0 || 313 (r = sshpkt_send(ssh)) != 0) 314 return r; 315 return 0; 316} 317 318static void 319kex_reset_dispatch(struct ssh *ssh) 320{ 321 ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN, 322 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); 323} 324 325static int 326kex_send_ext_info(struct ssh *ssh) 327{ 328 int r; 329 char *algs; 330 331 if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) 332 return SSH_ERR_ALLOC_FAIL; 333 /* XXX filter algs list by allowed pubkey/hostbased types */ 334 if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || 335 (r = sshpkt_put_u32(ssh, 1)) != 0 || 336 (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || 337 (r = sshpkt_put_cstring(ssh, algs)) != 0 || 338 (r = sshpkt_send(ssh)) != 0) 339 goto out; 340 /* success */ 341 r = 0; 342 out: 343 free(algs); 344 return r; 345} 346 347int 348kex_send_newkeys(struct ssh *ssh) 349{ 350 int r; 351 352 kex_reset_dispatch(ssh); 353 if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 || 354 (r = sshpkt_send(ssh)) != 0) 355 return r; 356 debug("SSH2_MSG_NEWKEYS sent"); 357 debug("expecting SSH2_MSG_NEWKEYS"); 358 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); 359 if (ssh->kex->ext_info_c) 360 if ((r = kex_send_ext_info(ssh)) != 0) 361 return r; 362 return 0; 363} 364 365int 366kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) 367{ 368 struct kex *kex = ssh->kex; 369 u_int32_t i, ninfo; 370 char *name; 371 u_char *val; 372 size_t vlen; 373 int r; 374 375 debug("SSH2_MSG_EXT_INFO received"); 376 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error); 377 if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0) 378 return r; 379 for (i = 0; i < ninfo; i++) { 380 if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) 381 return r; 382 if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) { 383 free(name); 384 return r; 385 } 386 if (strcmp(name, "server-sig-algs") == 0) { 387 /* Ensure no \0 lurking in value */ 388 if (memchr(val, '\0', vlen) != NULL) { 389 error("%s: nul byte in %s", __func__, name); 390 return SSH_ERR_INVALID_FORMAT; 391 } 392 debug("%s: %s=<%s>", __func__, name, val); 393 kex->server_sig_algs = val; 394 val = NULL; 395 } else 396 debug("%s: %s (unrecognised)", __func__, name); 397 free(name); 398 free(val); 399 } 400 return sshpkt_get_end(ssh); 401} 402 403static int 404kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) 405{ 406 struct kex *kex = ssh->kex; 407 int r; 408 409 debug("SSH2_MSG_NEWKEYS received"); 410 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); 411 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); 412 if ((r = sshpkt_get_end(ssh)) != 0) 413 return r; 414 if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0) 415 return r; 416 kex->done = 1; 417 sshbuf_reset(kex->peer); 418 /* sshbuf_reset(kex->my); */ 419 kex->flags &= ~KEX_INIT_SENT; 420 free(kex->name); 421 kex->name = NULL; 422 return 0; 423} 424 425int 426kex_send_kexinit(struct ssh *ssh) 427{ 428 u_char *cookie; 429 struct kex *kex = ssh->kex; 430 int r; 431 432 if (kex == NULL) 433 return SSH_ERR_INTERNAL_ERROR; 434 if (kex->flags & KEX_INIT_SENT) 435 return 0; 436 kex->done = 0; 437 438 /* generate a random cookie */ 439 if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) 440 return SSH_ERR_INVALID_FORMAT; 441 if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) 442 return SSH_ERR_INTERNAL_ERROR; 443 arc4random_buf(cookie, KEX_COOKIE_LEN); 444 445 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 || 446 (r = sshpkt_putb(ssh, kex->my)) != 0 || 447 (r = sshpkt_send(ssh)) != 0) 448 return r; 449 debug("SSH2_MSG_KEXINIT sent"); 450 kex->flags |= KEX_INIT_SENT; 451 return 0; 452} 453 454/* ARGSUSED */ 455int 456kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) 457{ 458 struct kex *kex = ssh->kex; 459 const u_char *ptr; 460 u_int i; 461 size_t dlen; 462 int r; 463 464 debug("SSH2_MSG_KEXINIT received"); 465 if (kex == NULL) 466 return SSH_ERR_INVALID_ARGUMENT; 467 468 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL); 469 ptr = sshpkt_ptr(ssh, &dlen); 470 if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) 471 return r; 472 473 /* discard packet */ 474 for (i = 0; i < KEX_COOKIE_LEN; i++) 475 if ((r = sshpkt_get_u8(ssh, NULL)) != 0) 476 return r; 477 for (i = 0; i < PROPOSAL_MAX; i++) 478 if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) 479 return r; 480 /* 481 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported 482 * KEX method has the server move first, but a server might be using 483 * a custom method or one that we otherwise don't support. We should 484 * be prepared to remember first_kex_follows here so we can eat a 485 * packet later. 486 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means 487 * for cases where the server *doesn't* go first. I guess we should 488 * ignore it when it is set for these cases, which is what we do now. 489 */ 490 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */ 491 (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */ 492 (r = sshpkt_get_end(ssh)) != 0) 493 return r; 494 495 if (!(kex->flags & KEX_INIT_SENT)) 496 if ((r = kex_send_kexinit(ssh)) != 0) 497 return r; 498 if ((r = kex_choose_conf(ssh)) != 0) 499 return r; 500 501 if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL) 502 return (kex->kex[kex->kex_type])(ssh); 503 504 return SSH_ERR_INTERNAL_ERROR; 505} 506 507int 508kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp) 509{ 510 struct kex *kex; 511 int r; 512 513 *kexp = NULL; 514 if ((kex = calloc(1, sizeof(*kex))) == NULL) 515 return SSH_ERR_ALLOC_FAIL; 516 if ((kex->peer = sshbuf_new()) == NULL || 517 (kex->my = sshbuf_new()) == NULL) { 518 r = SSH_ERR_ALLOC_FAIL; 519 goto out; 520 } 521 if ((r = kex_prop2buf(kex->my, proposal)) != 0) 522 goto out; 523 kex->done = 0; 524 kex_reset_dispatch(ssh); 525 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); 526 r = 0; 527 *kexp = kex; 528 out: 529 if (r != 0) 530 kex_free(kex); 531 return r; 532} 533 534void 535kex_free_newkeys(struct newkeys *newkeys) 536{ 537 if (newkeys == NULL) 538 return; 539 if (newkeys->enc.key) { 540 explicit_bzero(newkeys->enc.key, newkeys->enc.key_len); 541 free(newkeys->enc.key); 542 newkeys->enc.key = NULL; 543 } 544 if (newkeys->enc.iv) { 545 explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len); 546 free(newkeys->enc.iv); 547 newkeys->enc.iv = NULL; 548 } 549 free(newkeys->enc.name); 550 explicit_bzero(&newkeys->enc, sizeof(newkeys->enc)); 551 free(newkeys->comp.name); 552 explicit_bzero(&newkeys->comp, sizeof(newkeys->comp)); 553 mac_clear(&newkeys->mac); 554 if (newkeys->mac.key) { 555 explicit_bzero(newkeys->mac.key, newkeys->mac.key_len); 556 free(newkeys->mac.key); 557 newkeys->mac.key = NULL; 558 } 559 free(newkeys->mac.name); 560 explicit_bzero(&newkeys->mac, sizeof(newkeys->mac)); 561 explicit_bzero(newkeys, sizeof(*newkeys)); 562 free(newkeys); 563} 564 565void 566kex_free(struct kex *kex) 567{ 568 u_int mode; 569 570#ifdef WITH_OPENSSL 571 DH_free(kex->dh); 572 EC_KEY_free(kex->ec_client_key); 573#endif 574 for (mode = 0; mode < MODE_MAX; mode++) { 575 kex_free_newkeys(kex->newkeys[mode]); 576 kex->newkeys[mode] = NULL; 577 } 578 sshbuf_free(kex->peer); 579 sshbuf_free(kex->my); 580 free(kex->session_id); 581 free(kex->client_version_string); 582 free(kex->server_version_string); 583 free(kex->failed_choice); 584 free(kex->hostkey_alg); 585 free(kex->name); 586 free(kex); 587} 588 589int 590kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) 591{ 592 int r; 593 594 if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) 595 return r; 596 if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */ 597 kex_free(ssh->kex); 598 ssh->kex = NULL; 599 return r; 600 } 601 return 0; 602} 603 604/* 605 * Request key re-exchange, returns 0 on success or a ssherr.h error 606 * code otherwise. Must not be called if KEX is incomplete or in-progress. 607 */ 608int 609kex_start_rekex(struct ssh *ssh) 610{ 611 if (ssh->kex == NULL) { 612 error("%s: no kex", __func__); 613 return SSH_ERR_INTERNAL_ERROR; 614 } 615 if (ssh->kex->done == 0) { 616 error("%s: requested twice", __func__); 617 return SSH_ERR_INTERNAL_ERROR; 618 } 619 ssh->kex->done = 0; 620 return kex_send_kexinit(ssh); 621} 622 623static int 624choose_enc(struct sshenc *enc, char *client, char *server) 625{ 626 char *name = match_list(client, server, NULL); 627 628 if (name == NULL) 629 return SSH_ERR_NO_CIPHER_ALG_MATCH; 630 if ((enc->cipher = cipher_by_name(name)) == NULL) { 631 free(name); 632 return SSH_ERR_INTERNAL_ERROR; 633 } 634 enc->name = name; 635 enc->enabled = 0; 636 enc->iv = NULL; 637 enc->iv_len = cipher_ivlen(enc->cipher); 638 enc->key = NULL; 639 enc->key_len = cipher_keylen(enc->cipher); 640 enc->block_size = cipher_blocksize(enc->cipher); 641 return 0; 642} 643 644static int 645choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) 646{ 647 char *name = match_list(client, server, NULL); 648 649 if (name == NULL) 650 return SSH_ERR_NO_MAC_ALG_MATCH; 651 if (mac_setup(mac, name) < 0) { 652 free(name); 653 return SSH_ERR_INTERNAL_ERROR; 654 } 655 mac->name = name; 656 mac->key = NULL; 657 mac->enabled = 0; 658 return 0; 659} 660 661static int 662choose_comp(struct sshcomp *comp, char *client, char *server) 663{ 664 char *name = match_list(client, server, NULL); 665 666 if (name == NULL) 667 return SSH_ERR_NO_COMPRESS_ALG_MATCH; 668 if (strcmp(name, "zlib@openssh.com") == 0) { 669 comp->type = COMP_DELAYED; 670 } else if (strcmp(name, "zlib") == 0) { 671 comp->type = COMP_ZLIB; 672 } else if (strcmp(name, "none") == 0) { 673 comp->type = COMP_NONE; 674 } else { 675 free(name); 676 return SSH_ERR_INTERNAL_ERROR; 677 } 678 comp->name = name; 679 return 0; 680} 681 682static int 683choose_kex(struct kex *k, char *client, char *server) 684{ 685 const struct kexalg *kexalg; 686 687 k->name = match_list(client, server, NULL); 688 689 debug("kex: algorithm: %s", k->name ? k->name : "(no match)"); 690 if (k->name == NULL) 691 return SSH_ERR_NO_KEX_ALG_MATCH; 692 if ((kexalg = kex_alg_by_name(k->name)) == NULL) 693 return SSH_ERR_INTERNAL_ERROR; 694 k->kex_type = kexalg->type; 695 k->hash_alg = kexalg->hash_alg; 696 k->ec_nid = kexalg->ec_nid; 697 return 0; 698} 699 700static int 701choose_hostkeyalg(struct kex *k, char *client, char *server) 702{ 703 k->hostkey_alg = match_list(client, server, NULL); 704 705 debug("kex: host key algorithm: %s", 706 k->hostkey_alg ? k->hostkey_alg : "(no match)"); 707 if (k->hostkey_alg == NULL) 708 return SSH_ERR_NO_HOSTKEY_ALG_MATCH; 709 k->hostkey_type = sshkey_type_from_name(k->hostkey_alg); 710 if (k->hostkey_type == KEY_UNSPEC) 711 return SSH_ERR_INTERNAL_ERROR; 712 k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg); 713 return 0; 714} 715 716static int 717proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) 718{ 719 static int check[] = { 720 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1 721 }; 722 int *idx; 723 char *p; 724 725 for (idx = &check[0]; *idx != -1; idx++) { 726 if ((p = strchr(my[*idx], ',')) != NULL) 727 *p = '\0'; 728 if ((p = strchr(peer[*idx], ',')) != NULL) 729 *p = '\0'; 730 if (strcmp(my[*idx], peer[*idx]) != 0) { 731 debug2("proposal mismatch: my %s peer %s", 732 my[*idx], peer[*idx]); 733 return (0); 734 } 735 } 736 debug2("proposals match"); 737 return (1); 738} 739 740static int 741kex_choose_conf(struct ssh *ssh) 742{ 743 struct kex *kex = ssh->kex; 744 struct newkeys *newkeys; 745 char **my = NULL, **peer = NULL; 746 char **cprop, **sprop; 747 int nenc, nmac, ncomp; 748 u_int mode, ctos, need, dh_need, authlen; 749 int r, first_kex_follows; 750 751 debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); 752 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) 753 goto out; 754 debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server"); 755 if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) 756 goto out; 757 758 if (kex->server) { 759 cprop=peer; 760 sprop=my; 761 } else { 762 cprop=my; 763 sprop=peer; 764 } 765 766 /* Check whether client supports ext_info_c */ 767 if (kex->server) { 768 char *ext; 769 770 ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL); 771 kex->ext_info_c = (ext != NULL); 772 free(ext); 773 } 774 775 /* Algorithm Negotiation */ 776 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], 777 sprop[PROPOSAL_KEX_ALGS])) != 0) { 778 kex->failed_choice = peer[PROPOSAL_KEX_ALGS]; 779 peer[PROPOSAL_KEX_ALGS] = NULL; 780 goto out; 781 } 782 if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 783 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) { 784 kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS]; 785 peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL; 786 goto out; 787 } 788 for (mode = 0; mode < MODE_MAX; mode++) { 789 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) { 790 r = SSH_ERR_ALLOC_FAIL; 791 goto out; 792 } 793 kex->newkeys[mode] = newkeys; 794 ctos = (!kex->server && mode == MODE_OUT) || 795 (kex->server && mode == MODE_IN); 796 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; 797 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; 798 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; 799 if ((r = choose_enc(&newkeys->enc, cprop[nenc], 800 sprop[nenc])) != 0) { 801 kex->failed_choice = peer[nenc]; 802 peer[nenc] = NULL; 803 goto out; 804 } 805 authlen = cipher_authlen(newkeys->enc.cipher); 806 /* ignore mac for authenticated encryption */ 807 if (authlen == 0 && 808 (r = choose_mac(ssh, &newkeys->mac, cprop[nmac], 809 sprop[nmac])) != 0) { 810 kex->failed_choice = peer[nmac]; 811 peer[nmac] = NULL; 812 goto out; 813 } 814 if ((r = choose_comp(&newkeys->comp, cprop[ncomp], 815 sprop[ncomp])) != 0) { 816 kex->failed_choice = peer[ncomp]; 817 peer[ncomp] = NULL; 818 goto out; 819 } 820 debug("kex: %s cipher: %s MAC: %s compression: %s", 821 ctos ? "client->server" : "server->client", 822 newkeys->enc.name, 823 authlen == 0 ? newkeys->mac.name : "<implicit>", 824 newkeys->comp.name); 825 } 826 need = dh_need = 0; 827 for (mode = 0; mode < MODE_MAX; mode++) { 828 newkeys = kex->newkeys[mode]; 829 need = MAXIMUM(need, newkeys->enc.key_len); 830 need = MAXIMUM(need, newkeys->enc.block_size); 831 need = MAXIMUM(need, newkeys->enc.iv_len); 832 need = MAXIMUM(need, newkeys->mac.key_len); 833 dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher)); 834 dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); 835 dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); 836 dh_need = MAXIMUM(dh_need, newkeys->mac.key_len); 837 } 838 /* XXX need runden? */ 839 kex->we_need = need; 840 kex->dh_need = dh_need; 841 842 /* ignore the next message if the proposals do not match */ 843 if (first_kex_follows && !proposals_match(my, peer)) 844 ssh->dispatch_skip_packets = 1; 845 r = 0; 846 out: 847 kex_prop_free(my); 848 kex_prop_free(peer); 849 return r; 850} 851 852static int 853derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, 854 const struct sshbuf *shared_secret, u_char **keyp) 855{ 856 struct kex *kex = ssh->kex; 857 struct ssh_digest_ctx *hashctx = NULL; 858 char c = id; 859 u_int have; 860 size_t mdsz; 861 u_char *digest; 862 int r; 863 864 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) 865 return SSH_ERR_INVALID_ARGUMENT; 866 if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) { 867 r = SSH_ERR_ALLOC_FAIL; 868 goto out; 869 } 870 871 /* K1 = HASH(K || H || "A" || session_id) */ 872 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || 873 ssh_digest_update_buffer(hashctx, shared_secret) != 0 || 874 ssh_digest_update(hashctx, hash, hashlen) != 0 || 875 ssh_digest_update(hashctx, &c, 1) != 0 || 876 ssh_digest_update(hashctx, kex->session_id, 877 kex->session_id_len) != 0 || 878 ssh_digest_final(hashctx, digest, mdsz) != 0) { 879 r = SSH_ERR_LIBCRYPTO_ERROR; 880 goto out; 881 } 882 ssh_digest_free(hashctx); 883 hashctx = NULL; 884 885 /* 886 * expand key: 887 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1) 888 * Key = K1 || K2 || ... || Kn 889 */ 890 for (have = mdsz; need > have; have += mdsz) { 891 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || 892 ssh_digest_update_buffer(hashctx, shared_secret) != 0 || 893 ssh_digest_update(hashctx, hash, hashlen) != 0 || 894 ssh_digest_update(hashctx, digest, have) != 0 || 895 ssh_digest_final(hashctx, digest + have, mdsz) != 0) { 896 r = SSH_ERR_LIBCRYPTO_ERROR; 897 goto out; 898 } 899 ssh_digest_free(hashctx); 900 hashctx = NULL; 901 } 902#ifdef DEBUG_KEX 903 fprintf(stderr, "key '%c'== ", c); 904 dump_digest("key", digest, need); 905#endif 906 *keyp = digest; 907 digest = NULL; 908 r = 0; 909 out: 910 free(digest); 911 ssh_digest_free(hashctx); 912 return r; 913} 914 915#define NKEYS 6 916int 917kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen, 918 const struct sshbuf *shared_secret) 919{ 920 struct kex *kex = ssh->kex; 921 u_char *keys[NKEYS]; 922 u_int i, j, mode, ctos; 923 int r; 924 925 for (i = 0; i < NKEYS; i++) { 926 if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen, 927 shared_secret, &keys[i])) != 0) { 928 for (j = 0; j < i; j++) 929 free(keys[j]); 930 return r; 931 } 932 } 933 for (mode = 0; mode < MODE_MAX; mode++) { 934 ctos = (!kex->server && mode == MODE_OUT) || 935 (kex->server && mode == MODE_IN); 936 kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1]; 937 kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3]; 938 kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5]; 939 } 940 return 0; 941} 942 943#ifdef WITH_OPENSSL 944int 945kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen, 946 const BIGNUM *secret) 947{ 948 struct sshbuf *shared_secret; 949 int r; 950 951 if ((shared_secret = sshbuf_new()) == NULL) 952 return SSH_ERR_ALLOC_FAIL; 953 if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0) 954 r = kex_derive_keys(ssh, hash, hashlen, shared_secret); 955 sshbuf_free(shared_secret); 956 return r; 957} 958#endif 959 960 961#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 962void 963dump_digest(char *msg, u_char *digest, int len) 964{ 965 fprintf(stderr, "%s\n", msg); 966 sshbuf_dump_data(digest, len, stderr); 967} 968#endif 969