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