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