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