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