1 /*
   2  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  * 1. Redistributions of source code must retain the above copyright
   8  *    notice, this list of conditions and the following disclaimer.
   9  * 2. Redistributions in binary form must reproduce the above copyright
  10  *    notice, this list of conditions and the following disclaimer in the
  11  *    documentation and/or other materials provided with the distribution.
  12  *
  13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23  *
  24  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 
  28 #include "includes.h"
  29 RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $");
  30 
  31 #include <locale.h>
  32 
  33 #include <openssl/opensslconf.h>
  34 #include <openssl/crypto.h>
  35 
  36 #include "ssh2.h"
  37 #include "xmalloc.h"
  38 #include "buffer.h"
  39 #include "bufaux.h"
  40 #include "packet.h"
  41 #include "compat.h"
  42 #include "cipher.h"
  43 #include "kex.h"
  44 #include "key.h"
  45 #include "log.h"
  46 #include "mac.h"
  47 #include "match.h"
  48 #include "dispatch.h"
  49 #include "g11n.h"
  50 
  51 #ifdef GSSAPI
  52 #include "ssh-gss.h"
  53 #endif
  54 
  55 #define KEX_COOKIE_LEN  16
  56 
  57 char *session_lang = NULL;
  58 
  59 
  60 /* prototype */
  61 static void kex_do_hook(Kex *kex);
  62 static void kex_kexinit_finish(Kex *);
  63 static void kex_choose_conf(Kex *);
  64 
  65 /* put algorithm proposal into buffer */
  66 static
  67 void
  68 kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
  69 {
  70         int i;
  71 
  72         buffer_clear(b);
  73         /*
  74          * add a dummy cookie, the cookie will be overwritten by
  75          * kex_send_kexinit(), each time a kexinit is set
  76          */
  77         for (i = 0; i < KEX_COOKIE_LEN; i++)
  78                 buffer_put_char(b, 0);
  79         for (i = 0; i < PROPOSAL_MAX; i++)
  80                 buffer_put_cstring(b, proposal[i]);
  81         buffer_put_char(b, 0);                  /* first_kex_packet_follows */
  82         buffer_put_int(b, 0);                   /* uint32 reserved */
  83 }
  84 
  85 /* parse buffer and return algorithm proposal */
  86 static
  87 char **
  88 kex_buf2prop(Buffer *raw, int *first_kex_follows)
  89 {
  90         Buffer b;
  91         int i;
  92         char **proposal;
  93 
  94         proposal = xmalloc(PROPOSAL_MAX * sizeof(char *));
  95 
  96         buffer_init(&b);
  97         buffer_append(&b, buffer_ptr(raw), buffer_len(raw));
  98         /* skip cookie */
  99         for (i = 0; i < KEX_COOKIE_LEN; i++)
 100                 buffer_get_char(&b);
 101         /* extract kex init proposal strings */
 102         for (i = 0; i < PROPOSAL_MAX; i++) {
 103                 proposal[i] = buffer_get_string(&b,NULL);
 104                 debug2("kex_parse_kexinit: %s", proposal[i]);
 105         }
 106         /* first kex follows / reserved */
 107         i = buffer_get_char(&b);
 108         if (first_kex_follows != NULL)
 109                 *first_kex_follows = i;
 110         debug2("kex_parse_kexinit: first_kex_follows %d ", i);
 111         i = buffer_get_int(&b);
 112         debug2("kex_parse_kexinit: reserved %d ", i);
 113         buffer_free(&b);
 114         return proposal;
 115 }
 116 
 117 static
 118 void
 119 kex_prop_free(char **proposal)
 120 {
 121         int i;
 122 
 123         for (i = 0; i < PROPOSAL_MAX; i++)
 124                 xfree(proposal[i]);
 125         xfree(proposal);
 126 }
 127 
 128 static void
 129 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
 130 {
 131         error("Hm, kex protocol error: type %d seq %u", type, seq);
 132 }
 133 
 134 static void
 135 kex_reset_dispatch(void)
 136 {
 137 #ifdef ALTPRIVSEP
 138         /* unprivileged sshd has a kex packet handler that must not be reset */
 139         debug3("kex_reset_dispatch -- should we dispatch_set(KEXINIT) here? %d && !%d",
 140                 packet_is_server(), packet_is_monitor());
 141         if (packet_is_server() && !packet_is_monitor()) {
 142                 debug3("kex_reset_dispatch -- skipping dispatch_set(KEXINIT) in unpriv proc");
 143                 return;
 144         }
 145 #endif /* ALTPRIVSEP */
 146 
 147         dispatch_range(SSH2_MSG_TRANSPORT_MIN,
 148             SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
 149         dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
 150 }
 151 
 152 void
 153 kex_finish(Kex *kex)
 154 {
 155         kex_reset_dispatch();
 156 
 157         packet_start(SSH2_MSG_NEWKEYS);
 158         packet_send();
 159         /* packet_write_wait(); */
 160         debug("SSH2_MSG_NEWKEYS sent");
 161 
 162 #ifdef ALTPRIVSEP
 163         if (packet_is_monitor())
 164                 goto skip_newkeys;
 165 #endif /* ALTPRIVSEP */
 166         debug("expecting SSH2_MSG_NEWKEYS");
 167         packet_read_expect(SSH2_MSG_NEWKEYS);
 168         packet_check_eom();
 169         debug("SSH2_MSG_NEWKEYS received");
 170 #ifdef ALTPRIVSEP
 171 skip_newkeys:
 172 #endif /* ALTPRIVSEP */
 173 
 174         kex->done = 1;
 175         kex->initial_kex_done = 1; /* never to be cleared once set */
 176         buffer_clear(&kex->peer);
 177         /* buffer_clear(&kex->my); */
 178         kex->flags &= ~KEX_INIT_SENT;
 179         xfree(kex->name);
 180         kex->name = NULL;
 181 }
 182 
 183 void
 184 kex_send_kexinit(Kex *kex)
 185 {
 186         u_int32_t rand = 0;
 187         u_char *cookie;
 188         int i;
 189 
 190         if (kex == NULL) {
 191                 error("kex_send_kexinit: no kex, cannot rekey");
 192                 return;
 193         }
 194         if (kex->flags & KEX_INIT_SENT) {
 195                 debug("KEX_INIT_SENT");
 196                 return;
 197         }
 198         kex->done = 0;
 199 
 200         /* update my proposal -- e.g., add/remove GSS kexalgs */
 201         kex_do_hook(kex);
 202 
 203         /* generate a random cookie */
 204         if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
 205                 fatal("kex_send_kexinit: kex proposal too short");
 206         cookie = buffer_ptr(&kex->my);
 207         for (i = 0; i < KEX_COOKIE_LEN; i++) {
 208                 if (i % 4 == 0)
 209                         rand = arc4random();
 210                 cookie[i] = rand;
 211                 rand >>= 8;
 212         }
 213         packet_start(SSH2_MSG_KEXINIT);
 214         packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
 215         packet_send();
 216         debug("SSH2_MSG_KEXINIT sent");
 217         kex->flags |= KEX_INIT_SENT;
 218 }
 219 
 220 void
 221 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
 222 {
 223         char *ptr;
 224         u_int dlen;
 225         int i;
 226         Kex *kex = (Kex *)ctxt;
 227 
 228         debug("SSH2_MSG_KEXINIT received");
 229         if (kex == NULL)
 230                 fatal("kex_input_kexinit: no kex, cannot rekey");
 231 
 232         ptr = packet_get_raw(&dlen);
 233         buffer_append(&kex->peer, ptr, dlen);
 234 
 235         /* discard packet */
 236         for (i = 0; i < KEX_COOKIE_LEN; i++)
 237                 packet_get_char();
 238         for (i = 0; i < PROPOSAL_MAX; i++)
 239                 xfree(packet_get_string(NULL));
 240         (void) packet_get_char();
 241         (void) packet_get_int();
 242         packet_check_eom();
 243 
 244         kex_kexinit_finish(kex);
 245 }
 246 
 247 /*
 248  * This is for GSS keyex, where actual KEX offer can change at rekey
 249  * time due to credential expiration/renewal...
 250  */
 251 static
 252 void
 253 kex_do_hook(Kex *kex)
 254 {
 255         char    **prop;
 256 
 257         if (kex->kex_hook == NULL)
 258                 return;
 259 
 260         /* Unmarshall my proposal, let the hook modify it, remarshall it */
 261         prop = kex_buf2prop(&kex->my, NULL);
 262         buffer_clear(&kex->my);
 263         (kex->kex_hook)(kex, prop);
 264         kex_prop2buf(&kex->my, prop);
 265         kex_prop_free(prop);
 266 }
 267 
 268 /* Initiate the key exchange by sending the SSH2_MSG_KEXINIT message. */
 269 void
 270 kex_start(Kex *kex)
 271 {
 272         kex_send_kexinit(kex);
 273         kex_reset_dispatch();
 274 }
 275 
 276 /*
 277  * Allocate a key exchange structure and populate it with a proposal we are
 278  * going to use. This function does not start the actual key exchange.
 279  */
 280 Kex *
 281 kex_setup(const char *host, char *proposal[PROPOSAL_MAX], Kex_hook_func hook)
 282 {
 283         Kex     *kex;
 284 
 285         kex = xmalloc(sizeof(*kex));
 286         memset(kex, 0, sizeof(*kex));
 287         buffer_init(&kex->peer);
 288         buffer_init(&kex->my);
 289 
 290         kex->kex_hook = hook; /* called by kex_send_kexinit() */
 291 
 292         if (host != NULL && *host != '\0')
 293                 kex->serverhost = xstrdup(host);
 294         else
 295                 kex->server = 1;
 296 
 297         kex_prop2buf(&kex->my, proposal);
 298 
 299         return kex;
 300 }
 301 
 302 static void
 303 kex_kexinit_finish(Kex *kex)
 304 {
 305         if (!(kex->flags & KEX_INIT_SENT))
 306                 kex_send_kexinit(kex);
 307 
 308         kex_choose_conf(kex);
 309 
 310         if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX &&
 311             kex->kex[kex->kex_type] != NULL)
 312                 (kex->kex[kex->kex_type])(kex);
 313         else
 314                 fatal("Unsupported key exchange %d", kex->kex_type);
 315 }
 316 
 317 static void
 318 choose_lang(char **lang, char *client, char *server)
 319 {
 320         if (datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS)
 321                 *lang = match_list(client, server, NULL);
 322         else
 323                 *lang = g11n_srvr_locale_negotiate(client, NULL);
 324 }
 325 
 326 /*
 327  * Make the message clear enough so that if this happens the user can figure out
 328  * the workaround of changing the Ciphers option.
 329  */
 330 #define CLIENT_ERR_MSG                                                         \
 331   "Client and server could not agree on a common cipher:\n"                    \
 332   "  client: %s\n"                                                             \
 333   "  server: %s\n"                                                             \
 334   "\n"                                                                         \
 335   "The client cipher list can be controlled using the \"Ciphers\" option, \n"  \
 336   "see ssh_config(4) for more information. The \"-o Ciphers=<cipher-list>\"\n" \
 337   "option may be used to temporarily override the ciphers the client\n"        \
 338   "offers."
 339 
 340 /*
 341  * The server side message goes to syslogd and we do not want to send multiline
 342  * messages there. What's more, the server side notification may be shorter
 343  * since we expect that an administrator will deal with that, not the user.
 344  */
 345 #define SERVER_ERR_MSG                                                         \
 346   "Client and server could not agree on a common cipher: client \"%s\", "      \
 347   "server \"%s\". The server cipher list can be controlled using the "         \
 348   "\"Ciphers\" option, see sshd_config(4) for more information."
 349 
 350 static void
 351 choose_enc(int is_server, Enc *enc, char *client, char *server)
 352 {
 353         char *name = match_list(client, server, NULL);
 354 
 355         if (name == NULL) {
 356                 if (is_server == 1)
 357                         fatal(SERVER_ERR_MSG, client, server);
 358                 else
 359                         fatal(CLIENT_ERR_MSG, client, server);
 360         }
 361 
 362         if ((enc->cipher = cipher_by_name(name)) == NULL)
 363                 fatal("matching cipher is not supported: %s", name);
 364 
 365         enc->name = name;
 366         enc->enabled = 0;
 367         enc->iv = NULL;
 368         enc->key = NULL;
 369         enc->key_len = cipher_keylen(enc->cipher);
 370         enc->block_size = cipher_blocksize(enc->cipher);
 371 }
 372 
 373 static void
 374 choose_mac(Mac *mac, char *client, char *server)
 375 {
 376         char *name = match_list(client, server, NULL);
 377         if (name == NULL)
 378                 fatal("no matching mac found: client %s server %s",
 379                     client, server);
 380         if (mac_setup(mac, name) < 0)
 381                 fatal("unsupported mac %s", name);
 382         /* truncate the key */
 383         if (datafellows & SSH_BUG_HMAC)
 384                 mac->key_len = 16;
 385         mac->name = name;
 386         mac->key = NULL;
 387         mac->enabled = 0;
 388 }
 389 
 390 static void
 391 choose_comp(Comp *comp, char *client, char *server)
 392 {
 393         char *name = match_list(client, server, NULL);
 394         if (name == NULL)
 395                 fatal("no matching comp found: client %s server %s", client, server);
 396         if (strcmp(name, "zlib") == 0) {
 397                 comp->type = 1;
 398         } else if (strcmp(name, "none") == 0) {
 399                 comp->type = 0;
 400         } else {
 401                 fatal("unsupported comp %s", name);
 402         }
 403         comp->name = name;
 404 }
 405 
 406 static void
 407 choose_kex(Kex *k, char *client, char *server)
 408 {
 409         k->name = match_list(client, server, NULL);
 410         if (k->name == NULL)
 411                 fatal("no common kex alg: client '%s', server '%s'", client,
 412                     server);
 413         /* XXX Finish 3.6/7 merge of kex stuff -- choose_kex() done */
 414         if (strcmp(k->name, KEX_DH1) == 0) {
 415                 k->kex_type = KEX_DH_GRP1_SHA1;
 416         } else if (strcmp(k->name, KEX_DHGEX) == 0) {
 417                 k->kex_type = KEX_DH_GEX_SHA1;
 418 #ifdef GSSAPI
 419         } else if (strncmp(k->name, KEX_GSS_SHA1, sizeof(KEX_GSS_SHA1)-1) == 0) {
 420                 k->kex_type = KEX_GSS_GRP1_SHA1;
 421 #endif
 422         } else
 423                 fatal("bad kex alg %s", k->name);
 424 }
 425 
 426 static void
 427 choose_hostkeyalg(Kex *k, char *client, char *server)
 428 {
 429         char *hostkeyalg = match_list(client, server, NULL);
 430         if (hostkeyalg == NULL)
 431                 fatal("no hostkey alg");
 432         k->hostkey_type = key_type_from_name(hostkeyalg);
 433         if (k->hostkey_type == KEY_UNSPEC)
 434                 fatal("bad hostkey alg '%s'", hostkeyalg);
 435         xfree(hostkeyalg);
 436 }
 437 
 438 static int
 439 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
 440 {
 441         static int check[] = {
 442                 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
 443         };
 444         int *idx;
 445         char *p;
 446 
 447         for (idx = &check[0]; *idx != -1; idx++) {
 448                 if ((p = strchr(my[*idx], ',')) != NULL)
 449                         *p = '\0';
 450                 if ((p = strchr(peer[*idx], ',')) != NULL)
 451                         *p = '\0';
 452                 if (strcmp(my[*idx], peer[*idx]) != 0) {
 453                         debug2("proposal mismatch: my %s peer %s",
 454                             my[*idx], peer[*idx]);
 455                         return (0);
 456                 }
 457         }
 458         debug2("proposals match");
 459         return (1);
 460 }
 461 
 462 static void
 463 kex_choose_conf(Kex *kex)
 464 {
 465         Newkeys *newkeys;
 466         char **my, **peer;
 467         char **cprop, **sprop;
 468         char *p_langs_c2s, *p_langs_s2c; /* peer's langs */
 469         char *plangs = NULL;             /* peer's langs*/
 470         char *mlangs = NULL;             /* my langs */
 471         int nenc, nmac, ncomp;
 472         int mode;
 473         int ctos;                               /* direction: if true client-to-server */
 474         int need;
 475         int first_kex_follows, type;
 476 
 477         my   = kex_buf2prop(&kex->my, NULL);
 478         peer = kex_buf2prop(&kex->peer, &first_kex_follows);
 479 
 480         if (kex->server) {
 481                 cprop=peer;
 482                 sprop=my;
 483         } else {
 484                 cprop=my;
 485                 sprop=peer;
 486         }
 487 
 488         /* Algorithm Negotiation */
 489         for (mode = 0; mode < MODE_MAX; mode++) {
 490                 newkeys = xmalloc(sizeof(*newkeys));
 491                 memset(newkeys, 0, sizeof(*newkeys));
 492                 kex->newkeys[mode] = newkeys;
 493                 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
 494                 nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
 495                 nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
 496                 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
 497                 choose_enc(kex->server, &newkeys->enc,  cprop[nenc],  sprop[nenc]);
 498                 choose_mac(&newkeys->mac,  cprop[nmac],  sprop[nmac]);
 499                 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
 500                 debug("kex: %s %s %s %s",
 501                     ctos ? "client->server" : "server->client",
 502                     newkeys->enc.name,
 503                     newkeys->mac.name,
 504                     newkeys->comp.name);
 505         }
 506         choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
 507         choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
 508             sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
 509         need = 0;
 510         for (mode = 0; mode < MODE_MAX; mode++) {
 511                 newkeys = kex->newkeys[mode];
 512                 if (need < newkeys->enc.key_len)
 513                         need = newkeys->enc.key_len;
 514                 if (need < newkeys->enc.block_size)
 515                         need = newkeys->enc.block_size;
 516                 if (need < newkeys->mac.key_len)
 517                         need = newkeys->mac.key_len;
 518         }
 519         /* XXX need runden? */
 520         kex->we_need = need;
 521 
 522         /* ignore the next message if the proposals do not match */
 523         if (first_kex_follows && !proposals_match(my, peer) &&
 524             !(datafellows & SSH_BUG_FIRSTKEX)) {
 525                 type = packet_read();
 526                 debug2("skipping next packet (type %u)", type);
 527         }
 528 
 529         /* Language/locale negotiation -- not worth doing on re-key */
 530 
 531         if (!kex->initial_kex_done) {
 532                 p_langs_c2s = peer[PROPOSAL_LANG_CTOS];
 533                 p_langs_s2c = peer[PROPOSAL_LANG_STOC];
 534                 debug("Peer sent proposed langtags, ctos: %s", p_langs_c2s);
 535                 debug("Peer sent proposed langtags, stoc: %s", p_langs_s2c);
 536                 plangs = NULL;
 537 
 538                 /* We propose the same langs for each protocol direction */
 539                 mlangs = my[PROPOSAL_LANG_STOC];
 540                 debug("We proposed langtags, ctos: %s", my[PROPOSAL_LANG_CTOS]);
 541                 debug("We proposed langtags, stoc: %s", mlangs);
 542                 
 543                 /*
 544                  * Why oh why did they bother with negotiating langs for
 545                  * each protocol direction?!
 546                  *
 547                  * The semantics of this are vaguely specified, but one can
 548                  * imagine using one language (locale) for the whole session and
 549                  * a different one for message localization (e.g., 'en_US.UTF-8'
 550                  * overall and 'fr' for messages).  Weird?  Maybe.  But lang
 551                  * tags don't include codeset info, like locales do...
 552                  *
 553                  * So, server-side we want:
 554                  *  - setlocale(LC_ALL, c2s_locale);
 555                  *  and
 556                  *  - setlocale(LC_MESSAGES, s2c_locale);
 557                  *
 558                  * Client-side we don't really care.  But we could do:
 559                  *
 560                  *  - when very verbose, tell the use what lang the server's
 561                  *    messages are in, if left out in the protocol
 562                  *  - when sending messages to the server, and if applicable, we
 563                  *    can localize them according to the language negotiated for
 564                  *    that direction.
 565                  *
 566                  * But for now we do nothing on the client side.
 567                  */
 568                 if ((p_langs_c2s && *p_langs_c2s) && !(p_langs_s2c && *p_langs_s2c))
 569                         plangs = p_langs_c2s;
 570                 else if ((p_langs_s2c && *p_langs_s2c) && !(p_langs_c2s && *p_langs_c2s))
 571                         plangs = p_langs_s2c;
 572                 else
 573                         plangs = p_langs_c2s;
 574 
 575                 if (kex->server) {
 576                         if (plangs && mlangs && *plangs && *mlangs) {
 577                                 char *locale;
 578 
 579                                 g11n_test_langtag(plangs, 1);
 580 
 581                                 choose_lang(&locale, plangs, mlangs);
 582                                 if (locale) {
 583                                         g11n_setlocale(LC_ALL, locale);
 584                                         debug("Negotiated main locale: %s", locale);
 585                                         packet_send_debug("Negotiated main locale: %s", locale);
 586                                         xfree(locale);
 587                                 }
 588                                 if (plangs != p_langs_s2c &&
 589                                     p_langs_s2c && *p_langs_s2c) {
 590                                         choose_lang(&locale, p_langs_s2c, mlangs);
 591                                         if (locale) {
 592                                                 g11n_setlocale(LC_MESSAGES, locale);
 593                                                 debug("Negotiated messages locale: %s", locale);
 594                                                 packet_send_debug("Negotiated "
 595                                                     "messages locale: %s", locale);
 596                                                 xfree(locale);
 597                                         }
 598                                 }
 599                         }
 600                 }
 601                 else {
 602                         if (plangs && mlangs && *plangs && *mlangs &&
 603                             !(datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS)) {
 604                                 char *lang;
 605                                 lang = g11n_clnt_langtag_negotiate(mlangs, plangs);
 606                                 if (lang) {
 607                                         session_lang = lang;
 608                                         debug("Negotiated lang: %s", lang);
 609                                         g11n_test_langtag(lang, 0);
 610                                 }
 611                         }
 612                 }
 613         }
 614 
 615         kex_prop_free(my);
 616         kex_prop_free(peer);
 617 }
 618 
 619 static u_char *
 620 derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
 621 {
 622         Buffer b;
 623         const EVP_MD *evp_md = EVP_sha1();
 624         EVP_MD_CTX md;
 625         char c = id;
 626         int have;
 627         int mdsz = EVP_MD_size(evp_md);
 628         u_char *digest = xmalloc(roundup(need, mdsz));
 629 
 630         buffer_init(&b);
 631         buffer_put_bignum2(&b, shared_secret);
 632 
 633         /* K1 = HASH(K || H || "A" || session_id) */
 634         EVP_DigestInit(&md, evp_md);
 635         if (!(datafellows & SSH_BUG_DERIVEKEY))
 636                 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
 637         EVP_DigestUpdate(&md, hash, mdsz);
 638         EVP_DigestUpdate(&md, &c, 1);
 639         EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
 640         EVP_DigestFinal(&md, digest, NULL);
 641 
 642         /*
 643          * expand key:
 644          * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
 645          * Key = K1 || K2 || ... || Kn
 646          */
 647         for (have = mdsz; need > have; have += mdsz) {
 648                 EVP_DigestInit(&md, evp_md);
 649                 if (!(datafellows & SSH_BUG_DERIVEKEY))
 650                         EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
 651                 EVP_DigestUpdate(&md, hash, mdsz);
 652                 EVP_DigestUpdate(&md, digest, have);
 653                 EVP_DigestFinal(&md, digest + have, NULL);
 654         }
 655         buffer_free(&b);
 656 #ifdef DEBUG_KEX
 657         fprintf(stderr, "key '%c'== ", c);
 658         dump_digest("key", digest, need);
 659 #endif
 660         return digest;
 661 }
 662 
 663 Newkeys *current_keys[MODE_MAX];
 664 
 665 #define NKEYS   6
 666 void
 667 kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
 668 {
 669         u_char *keys[NKEYS];
 670         int i, mode, ctos;
 671 
 672         for (i = 0; i < NKEYS; i++)
 673                 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);
 674 
 675         debug2("kex_derive_keys");
 676         for (mode = 0; mode < MODE_MAX; mode++) {
 677                 current_keys[mode] = kex->newkeys[mode];
 678                 kex->newkeys[mode] = NULL;
 679                 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
 680                 current_keys[mode]->enc.iv  = keys[ctos ? 0 : 1];
 681                 current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
 682                 current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
 683         }
 684 }
 685 
 686 Newkeys *
 687 kex_get_newkeys(int mode)
 688 {
 689         Newkeys *ret;
 690 
 691         ret = current_keys[mode];
 692         current_keys[mode] = NULL;
 693         return ret;
 694 }
 695 
 696 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
 697 void
 698 dump_digest(char *msg, u_char *digest, int len)
 699 {
 700         int i;
 701 
 702         fprintf(stderr, "%s\n", msg);
 703         for (i = 0; i< len; i++) {
 704                 fprintf(stderr, "%02x", digest[i]);
 705                 if (i%32 == 31)
 706                         fprintf(stderr, "\n");
 707                 else if (i%8 == 7)
 708                         fprintf(stderr, " ");
 709         }
 710         fprintf(stderr, "\n");
 711 }
 712 #endif