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