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