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