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