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