xref: /freebsd/crypto/openssh/kex.c (revision 2574974648c68c738aec3ff96644d888d7913a37)
1 /* $OpenBSD: kex.c,v 1.193 2026/03/05 05:40:35 djm Exp $ */
2 /*
3  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "includes.h"
27 
28 #include <sys/types.h>
29 #include <errno.h>
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 #ifdef WITH_OPENSSL
38 #include <openssl/crypto.h>
39 #include <openssl/dh.h>
40 #endif
41 
42 #include "ssh.h"
43 #include "ssh2.h"
44 #include "atomicio.h"
45 #include "version.h"
46 #include "packet.h"
47 #include "compat.h"
48 #include "cipher.h"
49 #include "sshkey.h"
50 #include "kex.h"
51 #include "log.h"
52 #include "mac.h"
53 #include "match.h"
54 #include "misc.h"
55 #include "dispatch.h"
56 #include "myproposal.h"
57 
58 #include "ssherr.h"
59 #include "sshbuf.h"
60 #include "digest.h"
61 #include "xmalloc.h"
62 
63 /* prototype */
64 static int kex_choose_conf(struct ssh *, uint32_t seq);
65 static int kex_input_newkeys(int, uint32_t, struct ssh *);
66 
67 static const char * const proposal_names[PROPOSAL_MAX] = {
68 	"KEX algorithms",
69 	"host key algorithms",
70 	"ciphers ctos",
71 	"ciphers stoc",
72 	"MACs ctos",
73 	"MACs stoc",
74 	"compression ctos",
75 	"compression stoc",
76 	"languages ctos",
77 	"languages stoc",
78 };
79 
80 /*
81  * Fill out a proposal array with dynamically allocated values, which may
82  * be modified as required for compatibility reasons.
83  * Any of the options may be NULL, in which case the default is used.
84  * Array contents must be freed by calling kex_proposal_free_entries.
85  */
86 void
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;
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 	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error);
628 	ptr = sshpkt_ptr(ssh, &dlen);
629 	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
630 		return r;
631 
632 	/* discard packet */
633 	for (i = 0; i < KEX_COOKIE_LEN; i++) {
634 		if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
635 			error_fr(r, "discard cookie");
636 			return r;
637 		}
638 	}
639 	for (i = 0; i < PROPOSAL_MAX; i++) {
640 		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
641 			error_fr(r, "discard proposal");
642 			return r;
643 		}
644 	}
645 	/*
646 	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
647 	 * KEX method has the server move first, but a server might be using
648 	 * a custom method or one that we otherwise don't support. We should
649 	 * be prepared to remember first_kex_follows here so we can eat a
650 	 * packet later.
651 	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
652 	 * for cases where the server *doesn't* go first. I guess we should
653 	 * ignore it when it is set for these cases, which is what we do now.
654 	 */
655 	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
656 	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
657 	    (r = sshpkt_get_end(ssh)) != 0)
658 			return r;
659 
660 	if (!(kex->flags & KEX_INIT_SENT))
661 		if ((r = kex_send_kexinit(ssh)) != 0)
662 			return r;
663 	if ((r = kex_choose_conf(ssh, seq)) != 0)
664 		return r;
665 
666 	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
667 		return (kex->kex[kex->kex_type])(ssh);
668 
669 	error_f("unknown kex type %u", kex->kex_type);
670 	return SSH_ERR_INTERNAL_ERROR;
671 }
672 
673 struct kex *
kex_new(void)674 kex_new(void)
675 {
676 	struct kex *kex;
677 
678 	if ((kex = calloc(1, sizeof(*kex))) == NULL ||
679 	    (kex->peer = sshbuf_new()) == NULL ||
680 	    (kex->my = sshbuf_new()) == NULL ||
681 	    (kex->client_version = sshbuf_new()) == NULL ||
682 	    (kex->server_version = sshbuf_new()) == NULL ||
683 	    (kex->session_id = sshbuf_new()) == NULL) {
684 		kex_free(kex);
685 		return NULL;
686 	}
687 	return kex;
688 }
689 
690 void
kex_free_newkeys(struct newkeys * newkeys)691 kex_free_newkeys(struct newkeys *newkeys)
692 {
693 	if (newkeys == NULL)
694 		return;
695 	if (newkeys->enc.key) {
696 		explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
697 		free(newkeys->enc.key);
698 		newkeys->enc.key = NULL;
699 	}
700 	if (newkeys->enc.iv) {
701 		explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
702 		free(newkeys->enc.iv);
703 		newkeys->enc.iv = NULL;
704 	}
705 	free(newkeys->enc.name);
706 	explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
707 	free(newkeys->comp.name);
708 	explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
709 	mac_clear(&newkeys->mac);
710 	if (newkeys->mac.key) {
711 		explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
712 		free(newkeys->mac.key);
713 		newkeys->mac.key = NULL;
714 	}
715 	free(newkeys->mac.name);
716 	explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
717 	freezero(newkeys, sizeof(*newkeys));
718 }
719 
720 void
kex_free(struct kex * kex)721 kex_free(struct kex *kex)
722 {
723 	u_int mode;
724 
725 	if (kex == NULL)
726 		return;
727 
728 #ifdef WITH_OPENSSL
729 	DH_free(kex->dh);
730 #ifdef OPENSSL_HAS_ECC
731 	EC_KEY_free(kex->ec_client_key);
732 #endif /* OPENSSL_HAS_ECC */
733 #endif /* WITH_OPENSSL */
734 	for (mode = 0; mode < MODE_MAX; mode++) {
735 		kex_free_newkeys(kex->newkeys[mode]);
736 		kex->newkeys[mode] = NULL;
737 	}
738 	sshbuf_free(kex->peer);
739 	sshbuf_free(kex->my);
740 	sshbuf_free(kex->client_version);
741 	sshbuf_free(kex->server_version);
742 	sshbuf_free(kex->client_pub);
743 	sshbuf_free(kex->session_id);
744 	sshbuf_free(kex->initial_sig);
745 	sshkey_free(kex->initial_hostkey);
746 	free(kex->failed_choice);
747 	free(kex->hostkey_alg);
748 	free(kex->name);
749 	free(kex->server_sig_algs);
750 	free(kex);
751 }
752 
753 int
kex_ready(struct ssh * ssh,char * proposal[PROPOSAL_MAX])754 kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
755 {
756 	int r;
757 
758 	if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0)
759 		return r;
760 	ssh->kex->flags = KEX_INITIAL;
761 	kex_reset_dispatch(ssh);
762 	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
763 	return 0;
764 }
765 
766 int
kex_setup(struct ssh * ssh,char * proposal[PROPOSAL_MAX])767 kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
768 {
769 	int r;
770 
771 	if ((r = kex_ready(ssh, proposal)) != 0)
772 		return r;
773 	if ((r = kex_send_kexinit(ssh)) != 0) {		/* we start */
774 		kex_free(ssh->kex);
775 		ssh->kex = NULL;
776 		return r;
777 	}
778 	return 0;
779 }
780 
781 /*
782  * Request key re-exchange, returns 0 on success or a ssherr.h error
783  * code otherwise. Must not be called if KEX is incomplete or in-progress.
784  */
785 int
kex_start_rekex(struct ssh * ssh)786 kex_start_rekex(struct ssh *ssh)
787 {
788 	if (ssh->kex == NULL) {
789 		error_f("no kex");
790 		return SSH_ERR_INTERNAL_ERROR;
791 	}
792 	if (ssh->kex->done == 0) {
793 		error_f("requested twice");
794 		return SSH_ERR_INTERNAL_ERROR;
795 	}
796 	ssh->kex->done = 0;
797 	return kex_send_kexinit(ssh);
798 }
799 
800 static int
choose_enc(struct sshenc * enc,char * client,char * server)801 choose_enc(struct sshenc *enc, char *client, char *server)
802 {
803 	char *name = match_list(client, server, NULL);
804 
805 	if (name == NULL)
806 		return SSH_ERR_NO_CIPHER_ALG_MATCH;
807 	if ((enc->cipher = cipher_by_name(name)) == NULL) {
808 		error_f("unsupported cipher %s", name);
809 		free(name);
810 		return SSH_ERR_INTERNAL_ERROR;
811 	}
812 	enc->name = name;
813 	enc->enabled = 0;
814 	enc->iv = NULL;
815 	enc->iv_len = cipher_ivlen(enc->cipher);
816 	enc->key = NULL;
817 	enc->key_len = cipher_keylen(enc->cipher);
818 	enc->block_size = cipher_blocksize(enc->cipher);
819 	return 0;
820 }
821 
822 static int
choose_mac(struct ssh * ssh,struct sshmac * mac,char * client,char * server)823 choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
824 {
825 	char *name = match_list(client, server, NULL);
826 
827 	if (name == NULL)
828 		return SSH_ERR_NO_MAC_ALG_MATCH;
829 	if (mac_setup(mac, name) < 0) {
830 		error_f("unsupported MAC %s", name);
831 		free(name);
832 		return SSH_ERR_INTERNAL_ERROR;
833 	}
834 	mac->name = name;
835 	mac->key = NULL;
836 	mac->enabled = 0;
837 	return 0;
838 }
839 
840 static int
choose_comp(struct sshcomp * comp,char * client,char * server)841 choose_comp(struct sshcomp *comp, char *client, char *server)
842 {
843 	char *name = match_list(client, server, NULL);
844 
845 	if (name == NULL)
846 		return SSH_ERR_NO_COMPRESS_ALG_MATCH;
847 #ifdef WITH_ZLIB
848 	if (strcmp(name, "zlib@openssh.com") == 0) {
849 		comp->type = COMP_DELAYED;
850 	} else
851 #endif	/* WITH_ZLIB */
852 	if (strcmp(name, "none") == 0) {
853 		comp->type = COMP_NONE;
854 	} else {
855 		error_f("unsupported compression scheme %s", name);
856 		free(name);
857 		return SSH_ERR_INTERNAL_ERROR;
858 	}
859 	comp->name = name;
860 	return 0;
861 }
862 
863 static int
choose_kex(struct kex * k,char * client,char * server)864 choose_kex(struct kex *k, char *client, char *server)
865 {
866 	k->name = match_list(client, server, NULL);
867 
868 	debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
869 	if (k->name == NULL)
870 		return SSH_ERR_NO_KEX_ALG_MATCH;
871 	if (!kex_name_valid(k->name)) {
872 		error_f("unsupported KEX method %s", k->name);
873 		return SSH_ERR_INTERNAL_ERROR;
874 	}
875 	k->kex_type = kex_type_from_name(k->name);
876 	k->hash_alg = kex_hash_from_name(k->name);
877 	k->ec_nid = kex_nid_from_name(k->name);
878 	return 0;
879 }
880 
881 static int
choose_hostkeyalg(struct kex * k,char * client,char * server)882 choose_hostkeyalg(struct kex *k, char *client, char *server)
883 {
884 	free(k->hostkey_alg);
885 	k->hostkey_alg = match_list(client, server, NULL);
886 
887 	debug("kex: host key algorithm: %s",
888 	    k->hostkey_alg ? k->hostkey_alg : "(no match)");
889 	if (k->hostkey_alg == NULL)
890 		return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
891 	k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
892 	if (k->hostkey_type == KEY_UNSPEC) {
893 		error_f("unsupported hostkey algorithm %s", k->hostkey_alg);
894 		return SSH_ERR_INTERNAL_ERROR;
895 	}
896 	k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
897 	return 0;
898 }
899 
900 static int
proposals_match(char * my[PROPOSAL_MAX],char * peer[PROPOSAL_MAX])901 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
902 {
903 	static int check[] = {
904 		PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
905 	};
906 	int *idx;
907 	char *p;
908 
909 	for (idx = &check[0]; *idx != -1; idx++) {
910 		if ((p = strchr(my[*idx], ',')) != NULL)
911 			*p = '\0';
912 		if ((p = strchr(peer[*idx], ',')) != NULL)
913 			*p = '\0';
914 		if (strcmp(my[*idx], peer[*idx]) != 0) {
915 			debug2("proposal mismatch: my %s peer %s",
916 			    my[*idx], peer[*idx]);
917 			return (0);
918 		}
919 	}
920 	debug2("proposals match");
921 	return (1);
922 }
923 
924 static int
kexalgs_contains(char ** peer,const char * ext)925 kexalgs_contains(char **peer, const char *ext)
926 {
927 	return kex_has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
928 }
929 
930 static int
kex_choose_conf(struct ssh * ssh,uint32_t seq)931 kex_choose_conf(struct ssh *ssh, uint32_t seq)
932 {
933 	struct kex *kex = ssh->kex;
934 	struct newkeys *newkeys;
935 	char **my = NULL, **peer = NULL;
936 	char **cprop, **sprop;
937 	int nenc, nmac, ncomp;
938 	u_int mode, ctos, need, dh_need, authlen;
939 	int r, first_kex_follows;
940 
941 	debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
942 	if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
943 		goto out;
944 	debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
945 	if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
946 		goto out;
947 
948 	if (kex->server) {
949 		cprop=peer;
950 		sprop=my;
951 	} else {
952 		cprop=my;
953 		sprop=peer;
954 	}
955 
956 	/* Check whether peer supports ext_info/kex_strict */
957 	if ((kex->flags & KEX_INITIAL) != 0) {
958 		if (kex->server) {
959 			kex->ext_info_c = kexalgs_contains(peer, "ext-info-c");
960 			kex->kex_strict = kexalgs_contains(peer,
961 			    "kex-strict-c-v00@openssh.com");
962 		} else {
963 			kex->ext_info_s = kexalgs_contains(peer, "ext-info-s");
964 			kex->kex_strict = kexalgs_contains(peer,
965 			    "kex-strict-s-v00@openssh.com");
966 		}
967 		if (kex->kex_strict) {
968 			debug3_f("will use strict KEX ordering");
969 			if (seq != 0)
970 				ssh_packet_disconnect(ssh,
971 				    "strict KEX violation: "
972 				    "KEXINIT was not the first packet");
973 		}
974 	}
975 
976 	/* Check whether client supports rsa-sha2 algorithms */
977 	if (kex->server && (kex->flags & KEX_INITIAL)) {
978 		if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
979 		    "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
980 			kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
981 		if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
982 		    "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
983 			kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
984 	}
985 
986 	/* Algorithm Negotiation */
987 	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
988 	    sprop[PROPOSAL_KEX_ALGS])) != 0) {
989 		kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
990 		peer[PROPOSAL_KEX_ALGS] = NULL;
991 		goto out;
992 	}
993 	if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
994 	    sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
995 		kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
996 		peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
997 		goto out;
998 	}
999 	for (mode = 0; mode < MODE_MAX; mode++) {
1000 		if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
1001 			r = SSH_ERR_ALLOC_FAIL;
1002 			goto out;
1003 		}
1004 		kex->newkeys[mode] = newkeys;
1005 		ctos = (!kex->server && mode == MODE_OUT) ||
1006 		    (kex->server && mode == MODE_IN);
1007 		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
1008 		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
1009 		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
1010 		if ((r = choose_enc(&newkeys->enc, cprop[nenc],
1011 		    sprop[nenc])) != 0) {
1012 			kex->failed_choice = peer[nenc];
1013 			peer[nenc] = NULL;
1014 			goto out;
1015 		}
1016 		authlen = cipher_authlen(newkeys->enc.cipher);
1017 		/* ignore mac for authenticated encryption */
1018 		if (authlen == 0 &&
1019 		    (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
1020 		    sprop[nmac])) != 0) {
1021 			kex->failed_choice = peer[nmac];
1022 			peer[nmac] = NULL;
1023 			goto out;
1024 		}
1025 		if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
1026 		    sprop[ncomp])) != 0) {
1027 			kex->failed_choice = peer[ncomp];
1028 			peer[ncomp] = NULL;
1029 			goto out;
1030 		}
1031 		debug("kex: %s cipher: %s MAC: %s compression: %s",
1032 		    ctos ? "client->server" : "server->client",
1033 		    newkeys->enc.name,
1034 		    authlen == 0 ? newkeys->mac.name : "<implicit>",
1035 		    newkeys->comp.name);
1036 	}
1037 	need = dh_need = 0;
1038 	for (mode = 0; mode < MODE_MAX; mode++) {
1039 		newkeys = kex->newkeys[mode];
1040 		need = MAXIMUM(need, newkeys->enc.key_len);
1041 		need = MAXIMUM(need, newkeys->enc.block_size);
1042 		need = MAXIMUM(need, newkeys->enc.iv_len);
1043 		need = MAXIMUM(need, newkeys->mac.key_len);
1044 		dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));
1045 		dh_need = MAXIMUM(dh_need, newkeys->enc.block_size);
1046 		dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);
1047 		dh_need = MAXIMUM(dh_need, newkeys->mac.key_len);
1048 	}
1049 	/* XXX need runden? */
1050 	kex->we_need = need;
1051 	kex->dh_need = dh_need;
1052 
1053 	/* ignore the next message if the proposals do not match */
1054 	if (first_kex_follows && !proposals_match(my, peer))
1055 		ssh->dispatch_skip_packets = 1;
1056 	r = 0;
1057  out:
1058 	kex_prop_free(my);
1059 	kex_prop_free(peer);
1060 	return r;
1061 }
1062 
1063 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)1064 derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
1065     const struct sshbuf *shared_secret, u_char **keyp)
1066 {
1067 	struct kex *kex = ssh->kex;
1068 	struct ssh_digest_ctx *hashctx = NULL;
1069 	char c = id;
1070 	u_int have;
1071 	size_t mdsz;
1072 	u_char *digest;
1073 	int r;
1074 
1075 	if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
1076 		return SSH_ERR_INVALID_ARGUMENT;
1077 	if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {
1078 		r = SSH_ERR_ALLOC_FAIL;
1079 		goto out;
1080 	}
1081 
1082 	/* K1 = HASH(K || H || "A" || session_id) */
1083 	if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
1084 	    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
1085 	    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
1086 	    ssh_digest_update(hashctx, &c, 1) != 0 ||
1087 	    ssh_digest_update_buffer(hashctx, kex->session_id) != 0 ||
1088 	    ssh_digest_final(hashctx, digest, mdsz) != 0) {
1089 		r = SSH_ERR_LIBCRYPTO_ERROR;
1090 		error_f("KEX hash failed");
1091 		goto out;
1092 	}
1093 	ssh_digest_free(hashctx);
1094 	hashctx = NULL;
1095 
1096 	/*
1097 	 * expand key:
1098 	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
1099 	 * Key = K1 || K2 || ... || Kn
1100 	 */
1101 	for (have = mdsz; need > have; have += mdsz) {
1102 		if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
1103 		    ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
1104 		    ssh_digest_update(hashctx, hash, hashlen) != 0 ||
1105 		    ssh_digest_update(hashctx, digest, have) != 0 ||
1106 		    ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
1107 			error_f("KDF failed");
1108 			r = SSH_ERR_LIBCRYPTO_ERROR;
1109 			goto out;
1110 		}
1111 		ssh_digest_free(hashctx);
1112 		hashctx = NULL;
1113 	}
1114 #ifdef DEBUG_KEX
1115 	fprintf(stderr, "key '%c'== ", c);
1116 	dump_digest("key", digest, need);
1117 #endif
1118 	*keyp = digest;
1119 	digest = NULL;
1120 	r = 0;
1121  out:
1122 	free(digest);
1123 	ssh_digest_free(hashctx);
1124 	return r;
1125 }
1126 
1127 #define NKEYS	6
1128 int
kex_derive_keys(struct ssh * ssh,u_char * hash,u_int hashlen,const struct sshbuf * shared_secret)1129 kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
1130     const struct sshbuf *shared_secret)
1131 {
1132 	struct kex *kex = ssh->kex;
1133 	u_char *keys[NKEYS];
1134 	u_int i, j, mode, ctos;
1135 	int r;
1136 
1137 	/* save initial hash as session id */
1138 	if ((kex->flags & KEX_INITIAL) != 0) {
1139 		if (sshbuf_len(kex->session_id) != 0) {
1140 			error_f("already have session ID at kex");
1141 			return SSH_ERR_INTERNAL_ERROR;
1142 		}
1143 		if ((r = sshbuf_put(kex->session_id, hash, hashlen)) != 0)
1144 			return r;
1145 	} else if (sshbuf_len(kex->session_id) == 0) {
1146 		error_f("no session ID in rekex");
1147 		return SSH_ERR_INTERNAL_ERROR;
1148 	}
1149 	for (i = 0; i < NKEYS; i++) {
1150 		if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
1151 		    shared_secret, &keys[i])) != 0) {
1152 			for (j = 0; j < i; j++)
1153 				free(keys[j]);
1154 			return r;
1155 		}
1156 	}
1157 	for (mode = 0; mode < MODE_MAX; mode++) {
1158 		ctos = (!kex->server && mode == MODE_OUT) ||
1159 		    (kex->server && mode == MODE_IN);
1160 		kex->newkeys[mode]->enc.iv  = keys[ctos ? 0 : 1];
1161 		kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
1162 		kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
1163 	}
1164 	return 0;
1165 }
1166 
1167 int
kex_load_hostkey(struct ssh * ssh,struct sshkey ** prvp,struct sshkey ** pubp)1168 kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp)
1169 {
1170 	struct kex *kex = ssh->kex;
1171 
1172 	*pubp = NULL;
1173 	*prvp = NULL;
1174 	if (kex->load_host_public_key == NULL ||
1175 	    kex->load_host_private_key == NULL) {
1176 		error_f("missing hostkey loader");
1177 		return SSH_ERR_INVALID_ARGUMENT;
1178 	}
1179 	*pubp = kex->load_host_public_key(kex->hostkey_type,
1180 	    kex->hostkey_nid, ssh);
1181 	*prvp = kex->load_host_private_key(kex->hostkey_type,
1182 	    kex->hostkey_nid, ssh);
1183 	if (*pubp == NULL)
1184 		return SSH_ERR_NO_HOSTKEY_LOADED;
1185 	return 0;
1186 }
1187 
1188 int
kex_verify_host_key(struct ssh * ssh,struct sshkey * server_host_key)1189 kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
1190 {
1191 	struct kex *kex = ssh->kex;
1192 
1193 	if (kex->verify_host_key == NULL) {
1194 		error_f("missing hostkey verifier");
1195 		return SSH_ERR_INVALID_ARGUMENT;
1196 	}
1197 	if (server_host_key->type != kex->hostkey_type ||
1198 	    (kex->hostkey_type == KEY_ECDSA &&
1199 	    server_host_key->ecdsa_nid != kex->hostkey_nid))
1200 		return SSH_ERR_KEY_TYPE_MISMATCH;
1201 	if (kex->verify_host_key(server_host_key, ssh) == -1)
1202 		return  SSH_ERR_SIGNATURE_INVALID;
1203 	return 0;
1204 }
1205 
1206 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
1207 void
dump_digest(const char * msg,const u_char * digest,int len)1208 dump_digest(const char *msg, const u_char *digest, int len)
1209 {
1210 	fprintf(stderr, "%s\n", msg);
1211 	sshbuf_dump_data(digest, len, stderr);
1212 }
1213 #endif
1214 
1215 /*
1216  * Send a plaintext error message to the peer, suffixed by \r\n.
1217  * Only used during banner exchange, and there only for the server.
1218  */
1219 static void
send_error(struct ssh * ssh,char * msg)1220 send_error(struct ssh *ssh, char *msg)
1221 {
1222 	char *crnl = "\r\n";
1223 
1224 	if (!ssh->kex->server)
1225 		return;
1226 
1227 	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1228 	    msg, strlen(msg)) != strlen(msg) ||
1229 	    atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1230 	    crnl, strlen(crnl)) != strlen(crnl))
1231 		error_f("write: %.100s", strerror(errno));
1232 }
1233 
1234 /*
1235  * Sends our identification string and waits for the peer's. Will block for
1236  * up to timeout_ms (or indefinitely if timeout_ms <= 0).
1237  * Returns on 0 success or a ssherr.h code on failure.
1238  */
1239 int
kex_exchange_identification(struct ssh * ssh,int timeout_ms,const char * version_addendum)1240 kex_exchange_identification(struct ssh *ssh, int timeout_ms,
1241     const char *version_addendum)
1242 {
1243 	int remote_major, remote_minor, mismatch, oerrno = 0;
1244 	size_t len, n;
1245 	int r, expect_nl;
1246 	u_char c;
1247 	struct sshbuf *our_version = ssh->kex->server ?
1248 	    ssh->kex->server_version : ssh->kex->client_version;
1249 	struct sshbuf *peer_version = ssh->kex->server ?
1250 	    ssh->kex->client_version : ssh->kex->server_version;
1251 	char *our_version_string = NULL, *peer_version_string = NULL;
1252 	char *cp, *remote_version = NULL;
1253 
1254 	/* Prepare and send our banner */
1255 	sshbuf_reset(our_version);
1256 	if (version_addendum != NULL && *version_addendum == '\0')
1257 		version_addendum = NULL;
1258 	if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n",
1259 	    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
1260 	    version_addendum == NULL ? "" : " ",
1261 	    version_addendum == NULL ? "" : version_addendum)) != 0) {
1262 		oerrno = errno;
1263 		error_fr(r, "sshbuf_putf");
1264 		goto out;
1265 	}
1266 
1267 	if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
1268 	    sshbuf_mutable_ptr(our_version),
1269 	    sshbuf_len(our_version)) != sshbuf_len(our_version)) {
1270 		oerrno = errno;
1271 		debug_f("write: %.100s", strerror(errno));
1272 		r = SSH_ERR_SYSTEM_ERROR;
1273 		goto out;
1274 	}
1275 	if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
1276 		oerrno = errno;
1277 		error_fr(r, "sshbuf_consume_end");
1278 		goto out;
1279 	}
1280 	our_version_string = sshbuf_dup_string(our_version);
1281 	if (our_version_string == NULL) {
1282 		error_f("sshbuf_dup_string failed");
1283 		r = SSH_ERR_ALLOC_FAIL;
1284 		goto out;
1285 	}
1286 	debug("Local version string %.100s", our_version_string);
1287 
1288 	/* Read other side's version identification. */
1289 	for (n = 0; ; n++) {
1290 		if (n >= SSH_MAX_PRE_BANNER_LINES) {
1291 			send_error(ssh, "No SSH identification string "
1292 			    "received.");
1293 			error_f("No SSH version received in first %u lines "
1294 			    "from server", SSH_MAX_PRE_BANNER_LINES);
1295 			r = SSH_ERR_INVALID_FORMAT;
1296 			goto out;
1297 		}
1298 		sshbuf_reset(peer_version);
1299 		expect_nl = 0;
1300 		for (;;) {
1301 			if (timeout_ms > 0) {
1302 				r = waitrfd(ssh_packet_get_connection_in(ssh),
1303 				    &timeout_ms, NULL);
1304 				if (r == -1 && errno == ETIMEDOUT) {
1305 					send_error(ssh, "Timed out waiting "
1306 					    "for SSH identification string.");
1307 					error("Connection timed out during "
1308 					    "banner exchange");
1309 					r = SSH_ERR_CONN_TIMEOUT;
1310 					goto out;
1311 				} else if (r == -1) {
1312 					oerrno = errno;
1313 					error_f("%s", strerror(errno));
1314 					r = SSH_ERR_SYSTEM_ERROR;
1315 					goto out;
1316 				}
1317 			}
1318 
1319 			len = atomicio(read, ssh_packet_get_connection_in(ssh),
1320 			    &c, 1);
1321 			if (len != 1 && errno == EPIPE) {
1322 				verbose_f("Connection closed by remote host");
1323 				r = SSH_ERR_CONN_CLOSED;
1324 				goto out;
1325 			} else if (len != 1) {
1326 				oerrno = errno;
1327 				error_f("read: %.100s", strerror(errno));
1328 				r = SSH_ERR_SYSTEM_ERROR;
1329 				goto out;
1330 			}
1331 			if (c == '\r') {
1332 				expect_nl = 1;
1333 				continue;
1334 			}
1335 			if (c == '\n')
1336 				break;
1337 			if (c == '\0' || expect_nl) {
1338 				verbose_f("banner line contains invalid "
1339 				    "characters");
1340 				goto invalid;
1341 			}
1342 			if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
1343 				oerrno = errno;
1344 				error_fr(r, "sshbuf_put");
1345 				goto out;
1346 			}
1347 			if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
1348 				verbose_f("banner line too long");
1349 				goto invalid;
1350 			}
1351 		}
1352 		/* Is this an actual protocol banner? */
1353 		if (sshbuf_len(peer_version) > 4 &&
1354 		    memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0)
1355 			break;
1356 		/* If not, then just log the line and continue */
1357 		if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
1358 			error_f("sshbuf_dup_string failed");
1359 			r = SSH_ERR_ALLOC_FAIL;
1360 			goto out;
1361 		}
1362 		/* Do not accept lines before the SSH ident from a client */
1363 		if (ssh->kex->server) {
1364 			verbose_f("client sent invalid protocol identifier "
1365 			    "\"%.256s\"", cp);
1366 			free(cp);
1367 			goto invalid;
1368 		}
1369 		debug_f("banner line %zu: %s", n, cp);
1370 		free(cp);
1371 	}
1372 	peer_version_string = sshbuf_dup_string(peer_version);
1373 	if (peer_version_string == NULL)
1374 		fatal_f("sshbuf_dup_string failed");
1375 	/* XXX must be same size for sscanf */
1376 	if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
1377 		error_f("calloc failed");
1378 		r = SSH_ERR_ALLOC_FAIL;
1379 		goto out;
1380 	}
1381 
1382 	/*
1383 	 * Check that the versions match.  In future this might accept
1384 	 * several versions and set appropriate flags to handle them.
1385 	 */
1386 	if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n",
1387 	    &remote_major, &remote_minor, remote_version) != 3) {
1388 		error("Bad remote protocol version identification: '%.100s'",
1389 		    peer_version_string);
1390  invalid:
1391 		send_error(ssh, "Invalid SSH identification string.");
1392 		r = SSH_ERR_INVALID_FORMAT;
1393 		goto out;
1394 	}
1395 	debug("Remote protocol version %d.%d, remote software version %.100s",
1396 	    remote_major, remote_minor, remote_version);
1397 	compat_banner(ssh, remote_version);
1398 
1399 	mismatch = 0;
1400 	switch (remote_major) {
1401 	case 2:
1402 		break;
1403 	case 1:
1404 		if (remote_minor != 99)
1405 			mismatch = 1;
1406 		break;
1407 	default:
1408 		mismatch = 1;
1409 		break;
1410 	}
1411 	if (mismatch) {
1412 		error("Protocol major versions differ: %d vs. %d",
1413 		    PROTOCOL_MAJOR_2, remote_major);
1414 		send_error(ssh, "Protocol major versions differ.");
1415 		r = SSH_ERR_NO_PROTOCOL_VERSION;
1416 		goto out;
1417 	}
1418 
1419 	if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) {
1420 		logit("probed from %s port %d with %s.  Don't panic.",
1421 		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1422 		    peer_version_string);
1423 		r = SSH_ERR_CONN_CLOSED; /* XXX */
1424 		goto out;
1425 	}
1426 	if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) {
1427 		logit("scanned from %s port %d with %s.  Don't panic.",
1428 		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
1429 		    peer_version_string);
1430 		r = SSH_ERR_CONN_CLOSED; /* XXX */
1431 		goto out;
1432 	}
1433 	/* success */
1434 	r = 0;
1435  out:
1436 	free(our_version_string);
1437 	free(peer_version_string);
1438 	free(remote_version);
1439 	if (r == SSH_ERR_SYSTEM_ERROR)
1440 		errno = oerrno;
1441 	return r;
1442 }
1443 
1444