Coverage Report

Created: 2026-03-11 06:40

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