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