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