1 /* $OpenBSD: kex.c,v 1.109 2015/07/30 00:01:34 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 #ifndef WIN32
29 #include <sys/param.h> /* MAX roundup */
30 #endif
31
32 #include <signal.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #ifdef WITH_OPENSSL
39 #include <openssl/crypto.h>
40 #endif
41
42 #include "ssh2.h"
43 #include "packet.h"
44 #include "compat.h"
45 #include "cipher.h"
46 #include "sshkey.h"
47 #include "kex.h"
48 #include "log.h"
49 #include "mac.h"
50 #include "match.h"
51 #include "misc.h"
52 #include "dispatch.h"
53 #include "monitor.h"
54 //#include "roaming.h"
55
56 #include "ssherr.h"
57 #include "sshbuf.h"
58 #include "digest.h"
59
60 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
61 # if defined(HAVE_EVP_SHA256)
62 # define evp_ssh_sha256 EVP_sha256
63 # else
64 extern const EVP_MD *evp_ssh_sha256(void);
65 # endif
66 #endif
67
68 /* prototype */
69 static int kex_choose_conf(ncrack_ssh_state *nstate);
70 //static int kex_input_newkeys(ncrack_ssh_state *nstate);
71 static int choose_enc(struct sshenc *enc, char *client, char *server);
72 static int choose_mac(ncrack_ssh_state *ssh, struct sshmac *mac, char *client, char *server);
73 static int choose_comp(struct sshcomp *comp, char *client, char *server);
74 static int choose_kex(struct kex *k, char *client, char *server);
75 static int choose_hostkeyalg(struct kex *k, char *client, char *server);
76 static int proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]);
77
78 static int
kex_choose_conf(ncrack_ssh_state * nstate)79 kex_choose_conf(ncrack_ssh_state *nstate)
80 {
81 struct kex *kex = nstate->kex;
82 struct newkeys *newkeys;
83 char **my = NULL, **peer = NULL;
84 char **cprop, **sprop;
85 int nenc, nmac, ncomp;
86 u_int mode, ctos, need, dh_need, authlen;
87 int r, first_kex_follows;
88
89 //printf("kex_choose_conf\n");
90
91 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 ||
92 (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
93 goto out;
94
95 if (kex->server) {
96 cprop=peer;
97 sprop=my;
98 } else {
99 cprop=my;
100 sprop=peer;
101 }
102
103 /* Check whether server offers roaming */
104 #if 0
105 if (!kex->server) {
106 char *roaming = match_list(KEX_RESUME,
107 peer[PROPOSAL_KEX_ALGS], NULL);
108
109 if (roaming) {
110 kex->roaming = 1;
111 free(roaming);
112 }
113 }
114 #endif
115
116 /* Algorithm Negotiation */
117 for (mode = 0; mode < MODE_MAX; mode++) {
118 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
119 r = SSH_ERR_ALLOC_FAIL;
120 goto out;
121 }
122 kex->newkeys[mode] = newkeys;
123 ctos = (!kex->server && mode == MODE_OUT) ||
124 (kex->server && mode == MODE_IN);
125 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
126 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
127 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
128 if ((r = choose_enc(&newkeys->enc, cprop[nenc],
129 sprop[nenc])) != 0) {
130 kex->failed_choice = peer[nenc];
131 peer[nenc] = NULL;
132 goto out;
133 }
134 authlen = cipher_authlen(newkeys->enc.cipher);
135 /* ignore mac for authenticated encryption */
136 if (authlen == 0 &&
137 (r = choose_mac(nstate, &newkeys->mac, cprop[nmac],
138 sprop[nmac])) != 0) {
139 kex->failed_choice = peer[nmac];
140 peer[nmac] = NULL;
141 goto out;
142 }
143 if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
144 sprop[ncomp])) != 0) {
145 kex->failed_choice = peer[ncomp];
146 peer[ncomp] = NULL;
147 goto out;
148 }
149 debug("kex: %s %s %s %s",
150 ctos ? "client->server" : "server->client",
151 newkeys->enc.name,
152 authlen == 0 ? newkeys->mac.name : "<implicit>",
153 newkeys->comp.name);
154 }
155 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
156 sprop[PROPOSAL_KEX_ALGS])) != 0) {
157 kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
158 peer[PROPOSAL_KEX_ALGS] = NULL;
159 goto out;
160 }
161 if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
162 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
163 kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
164 peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
165 goto out;
166 }
167 need = dh_need = 0;
168 for (mode = 0; mode < MODE_MAX; mode++) {
169 newkeys = kex->newkeys[mode];
170 need = MAX(need, newkeys->enc.key_len);
171 need = MAX(need, newkeys->enc.block_size);
172 need = MAX(need, newkeys->enc.iv_len);
173 need = MAX(need, newkeys->mac.key_len);
174 dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher));
175 dh_need = MAX(dh_need, newkeys->enc.block_size);
176 dh_need = MAX(dh_need, newkeys->enc.iv_len);
177 dh_need = MAX(dh_need, newkeys->mac.key_len);
178 }
179 /* XXX need runden? */
180 kex->we_need = need;
181 kex->dh_need = dh_need;
182
183 /* ignore the next message if the proposals do not match */
184 if (first_kex_follows && !proposals_match(my, peer) &&
185 !(nstate->compat & SSH_BUG_FIRSTKEX))
186 nstate->dispatch_skip_packets = 1; // ncrackTODO: check this
187 r = 0;
188 out:
189 kex_prop_free(my);
190 kex_prop_free(peer);
191 return r;
192 }
193
194
195
196
197 struct kexalg {
198 char *name;
199 u_int type;
200 int ec_nid;
201 int hash_alg;
202 };
203 static const struct kexalg kexalgs[] = {
204 #ifdef WITH_OPENSSL
205 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
206 { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
207 { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
208 #ifdef HAVE_EVP_SHA256
209 { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
210 #endif /* HAVE_EVP_SHA256 */
211 #ifdef OPENSSL_HAS_ECC
212 { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
213 NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
214 { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
215 SSH_DIGEST_SHA384 },
216 # ifdef OPENSSL_HAS_NISTP521
217 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
218 SSH_DIGEST_SHA512 },
219 # endif /* OPENSSL_HAS_NISTP521 */
220 #endif /* OPENSSL_HAS_ECC */
221 #endif /* WITH_OPENSSL */
222 #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
223 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
224 #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
225 { NULL, -1, -1, -1},
226 };
227
228
229 char *
kex_alg_list(char sep)230 kex_alg_list(char sep)
231 {
232 char *ret = NULL, *tmp;
233 size_t nlen, rlen = 0;
234 const struct kexalg *k;
235
236 for (k = kexalgs; k->name != NULL; k++) {
237 if (ret != NULL)
238 ret[rlen++] = sep;
239 nlen = strlen(k->name);
240 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
241 free(ret);
242 return NULL;
243 }
244 ret = tmp;
245 memcpy(ret + rlen, k->name, nlen + 1);
246 rlen += nlen;
247 }
248 return ret;
249 }
250
251 static const struct kexalg *
kex_alg_by_name(const char * name)252 kex_alg_by_name(const char *name)
253 {
254 const struct kexalg *k;
255
256 for (k = kexalgs; k->name != NULL; k++) {
257 if (strcmp(k->name, name) == 0)
258 return k;
259 }
260 return NULL;
261 }
262
263 /* Validate KEX method name list */
264 int
kex_names_valid(const char * names)265 kex_names_valid(const char *names)
266 {
267 char *s, *cp, *p;
268
269 if (names == NULL || strcmp(names, "") == 0)
270 return 0;
271 if ((s = cp = strdup(names)) == NULL)
272 return 0;
273 for ((p = strsep(&cp, ",")); p && *p != '\0';
274 (p = strsep(&cp, ","))) {
275 if (kex_alg_by_name(p) == NULL) {
276 ssh_error("Unsupported KEX algorithm \"%.100s\"", p);
277 free(s);
278 return 0;
279 }
280 }
281 debug3("kex names ok: [%s]", names);
282 free(s);
283 return 1;
284 }
285
286
287 /*
288 * Concatenate algorithm names, avoiding duplicates in the process.
289 * Caller must free returned string.
290 */
291 char *
kex_names_cat(const char * a,const char * b)292 kex_names_cat(const char *a, const char *b)
293 {
294 char *ret = NULL, *tmp = NULL, *cp, *p;
295 size_t len;
296
297 if (a == NULL || *a == '\0')
298 return NULL;
299 if (b == NULL || *b == '\0')
300 return strdup(a);
301 if (strlen(b) > 1024*1024)
302 return NULL;
303 len = strlen(a) + strlen(b) + 2;
304 if ((tmp = cp = strdup(b)) == NULL ||
305 (ret = calloc(1, len)) == NULL) {
306 free(tmp);
307 return NULL;
308 }
309 strlcpy(ret, a, len);
310 for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
311 if (match_list(ret, p, NULL) != NULL)
312 continue; /* Algorithm already present */
313 if (strlcat(ret, ",", len) >= len ||
314 strlcat(ret, p, len) >= len) {
315 free(tmp);
316 free(ret);
317 return NULL; /* Shouldn't happen */
318 }
319 }
320 free(tmp);
321 return ret;
322 }
323
324
325 /*
326 * Assemble a list of algorithms from a default list and a string from a
327 * configuration file. The user-provided string may begin with '+' to
328 * indicate that it should be appended to the default.
329 */
330 int
kex_assemble_names(const char * def,char ** list)331 kex_assemble_names(const char *def, char **list)
332 {
333 char *ret;
334
335 if (list == NULL || *list == NULL || **list == '\0') {
336 *list = strdup(def);
337 return 0;
338 }
339 if (**list != '+') {
340 return 0;
341 }
342
343 if ((ret = kex_names_cat(def, *list + 1)) == NULL)
344 return SSH_ERR_ALLOC_FAIL;
345 free(*list);
346 *list = ret;
347 return 0;
348 }
349
350
351 /* put algorithm proposal into buffer */
352 int
kex_prop2buf(struct sshbuf * b,char * proposal[PROPOSAL_MAX])353 kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
354 {
355 u_int i;
356 int r;
357
358 sshbuf_reset(b);
359
360 /*
361 * add a dummy cookie, the cookie will be overwritten by
362 * kex_send_kexinit(), each time a kexinit is set
363 */
364 for (i = 0; i < KEX_COOKIE_LEN; i++) {
365 if ((r = sshbuf_put_u8(b, 0)) != 0)
366 return r;
367 }
368 for (i = 0; i < PROPOSAL_MAX; i++) {
369 if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
370 return r;
371 }
372 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */
373 (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */
374 return r;
375 return 0;
376 }
377
378 /* parse buffer and return algorithm proposal */
379 int
kex_buf2prop(struct sshbuf * raw,int * first_kex_follows,char *** propp)380 kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
381 {
382 struct sshbuf *b = NULL;
383 u_char v;
384 u_int i;
385 char **proposal = NULL;
386 int r;
387
388 *propp = NULL;
389 if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
390 return SSH_ERR_ALLOC_FAIL;
391 if ((b = sshbuf_fromb(raw)) == NULL) {
392 r = SSH_ERR_ALLOC_FAIL;
393 goto out;
394 }
395 if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
396 goto out;
397 /* extract kex init proposal strings */
398 for (i = 0; i < PROPOSAL_MAX; i++) {
399 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
400 goto out;
401 debug2("kex_parse_kexinit: %s", proposal[i]);
402 }
403 /* first kex follows / reserved */
404 if ((r = sshbuf_get_u8(b, &v)) != 0 ||
405 (r = sshbuf_get_u32(b, &i)) != 0)
406 goto out;
407 if (first_kex_follows != NULL)
408 *first_kex_follows = i;
409 debug2("kex_parse_kexinit: first_kex_follows %d ", v);
410 debug2("kex_parse_kexinit: reserved %u ", i);
411 r = 0;
412 *propp = proposal;
413 out:
414 if (r != 0 && proposal != NULL)
415 kex_prop_free(proposal);
416 sshbuf_free(b);
417 return r;
418 }
419
420 void
kex_prop_free(char ** proposal)421 kex_prop_free(char **proposal)
422 {
423 u_int i;
424
425 if (proposal == NULL)
426 return;
427 for (i = 0; i < PROPOSAL_MAX; i++)
428 free(proposal[i]);
429 free(proposal);
430 }
431
432 #if 0
433 /* ARGSUSED */
434 static int
435 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
436 {
437 ssh_error("Hm, kex protocol error: type %d seq %u", type, seq);
438 return 0;
439 }
440 #endif
441
442 #if 0
443 static void
444 kex_reset_dispatch(struct ssh *ssh)
445 {
446 ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
447 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
448 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
449 }
450 #endif
451
452 int
kex_send_newkeys(ncrack_ssh_state * nstate)453 kex_send_newkeys(ncrack_ssh_state *nstate)
454 {
455 int r;
456
457 //kex_reset_dispatch(ssh);
458 if ((r = sshpkt_start(nstate, SSH2_MSG_NEWKEYS)) != 0 ||
459 (r = sshpkt_send(nstate)) != 0) {
460 //printf("kex send newkeys\n");
461 return r;
462 }
463 debug("SSH2_MSG_NEWKEYS sent");
464 debug("expecting SSH2_MSG_NEWKEYS");
465
466 //ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
467 return 0;
468 }
469
470 #if 0
471 static int
472 kex_input_newkeys(ncrack_ssh_state *nstate)
473 {
474 //struct ssh *ssh = ctxt;
475 struct kex *kex = nstate->kex;
476 int r;
477
478 debug("SSH2_MSG_NEWKEYS received");
479 //ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
480 if ((r = sshpkt_get_end(nstate)) != 0)
481 return r;
482 kex->done = 1;
483 sshbuf_reset(kex->peer);
484 /* sshbuf_reset(kex->my); */
485 kex->flags &= ~KEX_INIT_SENT;
486 free(kex->name);
487 kex->name = NULL;
488
489 return 0;
490 }
491 #endif
492
493
494 int
kex_send_kexinit(ncrack_ssh_state * nstate)495 kex_send_kexinit(ncrack_ssh_state *nstate)
496 {
497 u_char *cookie;
498 struct kex *kex = nstate->kex;
499 int r;
500
501 if (kex == NULL)
502 return SSH_ERR_INTERNAL_ERROR;
503 if (kex->flags & KEX_INIT_SENT)
504 return 0;
505 kex->done = 0;
506
507 /* generate a random cookie */
508 if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
509 return SSH_ERR_INVALID_FORMAT;
510 if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
511 return SSH_ERR_INTERNAL_ERROR;
512 arc4random_buf(cookie, KEX_COOKIE_LEN);
513
514 if ((r = sshpkt_start(nstate, SSH2_MSG_KEXINIT)) != 0 ||
515 (r = sshpkt_putb(nstate, kex->my)) != 0 ||
516 (r = sshpkt_send(nstate)) != 0)
517 return r;
518 debug("SSH2_MSG_KEXINIT sent");
519 kex->flags |= KEX_INIT_SENT;
520 return 0;
521 }
522
523
524 /* ARGSUSED */
525 int
ncrackssh_kex_input_kexinit(ncrack_ssh_state * nstate)526 ncrackssh_kex_input_kexinit(ncrack_ssh_state *nstate)
527 {
528 //struct ssh *ssh = ctxt;
529 struct kex *kex = nstate->kex;
530 const u_char *ptr;
531 u_int i;
532 size_t dlen;
533 int r;
534
535 debug("SSH2_MSG_KEXINIT received");
536 if (kex == NULL) {
537 return SSH_ERR_INVALID_ARGUMENT;
538 }
539
540 ptr = sshpkt_ptr(nstate, &dlen);
541 if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) {
542 return r;
543 }
544
545 /* discard packet */
546 for (i = 0; i < KEX_COOKIE_LEN; i++)
547 if ((r = sshpkt_get_u8(nstate, NULL)) != 0) {
548 return r;
549 }
550
551 for (i = 0; i < PROPOSAL_MAX; i++)
552 if ((r = sshpkt_get_string(nstate, NULL, NULL)) != 0) {
553 return r;
554 }
555 /*
556 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
557 * KEX method has the server move first, but a server might be using
558 * a custom method or one that we otherwise don't support. We should
559 * be prepared to remember first_kex_follows here so we can eat a
560 * packet later.
561 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
562 * for cases where the server *doesn't* go first. I guess we should
563 * ignore it when it is set for these cases, which is what we do now.
564 */
565
566 if ((r = sshpkt_get_u8(nstate, NULL)) != 0 || /* first_kex_follows */
567 (r = sshpkt_get_u32(nstate, NULL)) != 0 || /* reserved */
568 (r = sshpkt_get_end(nstate)) != 0)
569 return r;
570
571 if (!(kex->flags & KEX_INIT_SENT)) {
572 if ((r = kex_send_kexinit(nstate)) != 0)
573 return r;
574 }
575 if ((r = kex_choose_conf(nstate)) != 0)
576 return r;
577
578 if (kex->kex_type < KEX_MAX && kex->kexm[kex->kex_type] != NULL) {
579 //printf("kex type %d\n", kex->kex_type);
580 //printf("kex %d \n", kex->kex[kex->kex_type]);
581 return (kex->kexm[kex->kex_type])(nstate);
582 }
583
584 return SSH_ERR_INTERNAL_ERROR;
585 }
586
587
588 int
kex_new(ncrack_ssh_state * nstate,char * proposal[PROPOSAL_MAX],struct kex ** kexp)589 kex_new(ncrack_ssh_state *nstate, char *proposal[PROPOSAL_MAX], struct kex **kexp)
590 {
591 struct kex *kex;
592 int r;
593
594 *kexp = NULL;
595 if ((kex = calloc(1, sizeof(*kex))) == NULL)
596 return SSH_ERR_ALLOC_FAIL;
597 if ((kex->peer = sshbuf_new()) == NULL ||
598 (kex->my = sshbuf_new()) == NULL) {
599 r = SSH_ERR_ALLOC_FAIL;
600 goto out;
601 }
602 if ((r = kex_prop2buf(kex->my, proposal)) != 0)
603 goto out;
604 kex->done = 0;
605 //kex_reset_dispatch(ssh);
606 r = 0;
607 *kexp = kex;
608 out:
609 if (r != 0)
610 kex_free(kex);
611 return r;
612 }
613
614
615 void
kex_free_newkeys(struct newkeys * newkeys)616 kex_free_newkeys(struct newkeys *newkeys)
617 {
618 if (newkeys == NULL)
619 return;
620 if (newkeys->enc.key) {
621 explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
622 free(newkeys->enc.key);
623 newkeys->enc.key = NULL;
624 }
625 if (newkeys->enc.iv) {
626 explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
627 free(newkeys->enc.iv);
628 newkeys->enc.iv = NULL;
629 }
630 free(newkeys->enc.name);
631 explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
632 free(newkeys->comp.name);
633 explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
634 mac_clear(&newkeys->mac);
635 if (newkeys->mac.key) {
636 explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
637 free(newkeys->mac.key);
638 newkeys->mac.key = NULL;
639 }
640 free(newkeys->mac.name);
641 explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
642 explicit_bzero(newkeys, sizeof(*newkeys));
643 free(newkeys);
644 }
645
646 void
kex_free(struct kex * kex)647 kex_free(struct kex *kex)
648 {
649 u_int mode;
650
651 #ifdef WITH_OPENSSL
652 if (kex->dh)
653 DH_free(kex->dh);
654 #ifdef OPENSSL_HAS_ECC
655 if (kex->ec_client_key)
656 EC_KEY_free(kex->ec_client_key);
657 #endif /* OPENSSL_HAS_ECC */
658 #endif /* WITH_OPENSSL */
659 for (mode = 0; mode < MODE_MAX; mode++) {
660 kex_free_newkeys(kex->newkeys[mode]);
661 kex->newkeys[mode] = NULL;
662 }
663 sshbuf_free(kex->peer);
664 sshbuf_free(kex->my);
665 free(kex->session_id);
666 free(kex->client_version_string);
667 free(kex->server_version_string);
668 free(kex->failed_choice);
669 free(kex);
670 }
671
672 int
kex_setup(ncrack_ssh_state * nstate,char * proposal[PROPOSAL_MAX])673 kex_setup(ncrack_ssh_state *nstate, char *proposal[PROPOSAL_MAX])
674 {
675 int r;
676
677 if ((r = kex_new(nstate, proposal, &nstate->kex)) != 0) {
678 return r;
679 }
680 if ((r = kex_send_kexinit(nstate)) != 0) { /* we start */
681 kex_free(nstate->kex);
682 nstate->kex = NULL;
683 return r;
684 }
685
686 return 0;
687 }
688
689
690 static int
choose_enc(struct sshenc * enc,char * client,char * server)691 choose_enc(struct sshenc *enc, char *client, char *server)
692 {
693 char *name = match_list(client, server, NULL);
694
695 if (name == NULL)
696 return SSH_ERR_NO_CIPHER_ALG_MATCH;
697 if ((enc->cipher = cipher_by_name(name)) == NULL)
698 return SSH_ERR_INTERNAL_ERROR;
699 enc->name = name;
700 enc->enabled = 0;
701 enc->iv = NULL;
702 enc->iv_len = cipher_ivlen(enc->cipher);
703 enc->key = NULL;
704 enc->key_len = cipher_keylen(enc->cipher);
705 enc->block_size = cipher_blocksize(enc->cipher);
706 return 0;
707 }
708
709 static int
choose_mac(ncrack_ssh_state * nstate,struct sshmac * mac,char * client,char * server)710 choose_mac(ncrack_ssh_state *nstate, struct sshmac *mac, char *client, char *server)
711 {
712 char *name = match_list(client, server, NULL);
713
714 if (name == NULL)
715 return SSH_ERR_NO_MAC_ALG_MATCH;
716 if (mac_setup(mac, name) < 0)
717 return SSH_ERR_INTERNAL_ERROR;
718 /* truncate the key */
719 if (nstate->compat & SSH_BUG_HMAC)
720 mac->key_len = 16;
721 mac->name = name;
722 mac->key = NULL;
723 mac->enabled = 0;
724 return 0;
725 }
726
727 static int
choose_comp(struct sshcomp * comp,char * client,char * server)728 choose_comp(struct sshcomp *comp, char *client, char *server)
729 {
730 char *name = match_list(client, server, NULL);
731
732 if (name == NULL)
733 return SSH_ERR_NO_COMPRESS_ALG_MATCH;
734 if (strcmp(name, "zlib@openssh.com") == 0) {
735 comp->type = COMP_DELAYED;
736 } else if (strcmp(name, "zlib") == 0) {
737 comp->type = COMP_ZLIB;
738 } else if (strcmp(name, "none") == 0) {
739 comp->type = COMP_NONE;
740 } else {
741 return SSH_ERR_INTERNAL_ERROR;
742 }
743 comp->name = name;
744 return 0;
745 }
746
747 static int
choose_kex(struct kex * k,char * client,char * server)748 choose_kex(struct kex *k, char *client, char *server)
749 {
750 const struct kexalg *kexalg;
751
752 k->name = match_list(client, server, NULL);
753
754 if (k->name == NULL)
755 return SSH_ERR_NO_KEX_ALG_MATCH;
756 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
757 return SSH_ERR_INTERNAL_ERROR;
758 k->kex_type = kexalg->type;
759 k->hash_alg = kexalg->hash_alg;
760 k->ec_nid = kexalg->ec_nid;
761 return 0;
762 }
763
764 static int
choose_hostkeyalg(struct kex * k,char * client,char * server)765 choose_hostkeyalg(struct kex *k, char *client, char *server)
766 {
767 char *hostkeyalg = match_list(client, server, NULL);
768
769 if (hostkeyalg == NULL)
770 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
771 k->hostkey_type = sshkey_type_from_name(hostkeyalg);
772 if (k->hostkey_type == KEY_UNSPEC)
773 return SSH_ERR_INTERNAL_ERROR;
774 k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg);
775 free(hostkeyalg);
776 return 0;
777 }
778
779 static int
proposals_match(char * my[PROPOSAL_MAX],char * peer[PROPOSAL_MAX])780 proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
781 {
782 static int check[] = {
783 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
784 };
785 int *idx;
786 char *p;
787
788 for (idx = &check[0]; *idx != -1; idx++) {
789 if ((p = strchr(my[*idx], ',')) != NULL)
790 *p = '\0';
791 if ((p = strchr(peer[*idx], ',')) != NULL)
792 *p = '\0';
793 if (strcmp(my[*idx], peer[*idx]) != 0) {
794 debug2("proposal mismatch: my %s peer %s",
795 my[*idx], peer[*idx]);
796 return (0);
797 }
798 }
799 debug2("proposals match");
800 return (1);
801 }
802
803
804 static int
derive_key(ncrack_ssh_state * nstate,int id,u_int need,u_char * hash,u_int hashlen,const struct sshbuf * shared_secret,u_char ** keyp)805 derive_key(ncrack_ssh_state *nstate, int id, u_int need, u_char *hash, u_int hashlen,
806 const struct sshbuf *shared_secret, u_char **keyp)
807 {
808 struct kex *kex = nstate->kex;
809 struct ssh_digest_ctx *hashctx = NULL;
810 char c = id;
811 u_int have;
812 size_t mdsz;
813 u_char *digest;
814 int r;
815
816 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
817 return SSH_ERR_INVALID_ARGUMENT;
818 if ((digest = calloc(1, roundup(need, mdsz))) == NULL) {
819 r = SSH_ERR_ALLOC_FAIL;
820 goto out;
821 }
822
823 /* K1 = HASH(K || H || "A" || session_id) */
824 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
825 ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
826 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
827 ssh_digest_update(hashctx, &c, 1) != 0 ||
828 ssh_digest_update(hashctx, kex->session_id,
829 kex->session_id_len) != 0 ||
830 ssh_digest_final(hashctx, digest, mdsz) != 0) {
831 r = SSH_ERR_LIBCRYPTO_ERROR;
832 goto out;
833 }
834 ssh_digest_free(hashctx);
835 hashctx = NULL;
836
837 /*
838 * expand key:
839 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
840 * Key = K1 || K2 || ... || Kn
841 */
842 for (have = mdsz; need > have; have += mdsz) {
843 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
844 ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
845 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
846 ssh_digest_update(hashctx, digest, have) != 0 ||
847 ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
848 r = SSH_ERR_LIBCRYPTO_ERROR;
849 goto out;
850 }
851 ssh_digest_free(hashctx);
852 hashctx = NULL;
853 }
854 #ifdef DEBUG_KEX
855 fprintf(stderr, "key '%c'== ", c);
856 dump_digest("key", digest, need);
857 #endif
858 *keyp = digest;
859 digest = NULL;
860 r = 0;
861 out:
862 if (digest)
863 free(digest);
864 ssh_digest_free(hashctx);
865 return r;
866 }
867
868 #define NKEYS 6
869 int
kex_derive_keys(ncrack_ssh_state * nstate,u_char * hash,u_int hashlen,const struct sshbuf * shared_secret)870 kex_derive_keys(ncrack_ssh_state *nstate, u_char *hash, u_int hashlen,
871 const struct sshbuf *shared_secret)
872 {
873 struct kex *kex = nstate->kex;
874 u_char *keys[NKEYS];
875 u_int i, j, mode, ctos;
876 int r;
877
878 for (i = 0; i < NKEYS; i++) {
879 if ((r = derive_key(nstate, 'A'+i, kex->we_need, hash, hashlen,
880 shared_secret, &keys[i])) != 0) {
881 for (j = 0; j < i; j++)
882 free(keys[j]);
883 return r;
884 }
885 }
886 for (mode = 0; mode < MODE_MAX; mode++) {
887 ctos = (!kex->server && mode == MODE_OUT) ||
888 (kex->server && mode == MODE_IN);
889 kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];
890 kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
891 kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
892 }
893 return 0;
894 }
895
896 #ifdef WITH_OPENSSL
897 int
kex_derive_keys_bn(ncrack_ssh_state * nstate,u_char * hash,u_int hashlen,const BIGNUM * secret)898 kex_derive_keys_bn(ncrack_ssh_state *nstate, u_char *hash, u_int hashlen,
899 const BIGNUM *secret)
900 {
901 struct sshbuf *shared_secret;
902 int r;
903
904 if ((shared_secret = sshbuf_new()) == NULL)
905 return SSH_ERR_ALLOC_FAIL;
906 if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
907 r = kex_derive_keys(nstate, hash, hashlen, shared_secret);
908 sshbuf_free(shared_secret);
909 return r;
910 }
911 #endif
912
913 #ifdef WITH_SSH1
914 int
derive_ssh1_session_id(BIGNUM * host_modulus,BIGNUM * server_modulus,u_int8_t cookie[8],u_int8_t id[16])915 derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
916 u_int8_t cookie[8], u_int8_t id[16])
917 {
918 u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
919 struct ssh_digest_ctx *hashctx = NULL;
920 size_t hlen, slen;
921 int r;
922
923 hlen = BN_num_bytes(host_modulus);
924 slen = BN_num_bytes(server_modulus);
925 if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
926 slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
927 return SSH_ERR_KEY_BITS_MISMATCH;
928 if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
929 BN_bn2bin(server_modulus, sbuf) <= 0) {
930 r = SSH_ERR_LIBCRYPTO_ERROR;
931 goto out;
932 }
933 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
934 r = SSH_ERR_ALLOC_FAIL;
935 goto out;
936 }
937 if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
938 ssh_digest_update(hashctx, sbuf, slen) != 0 ||
939 ssh_digest_update(hashctx, cookie, 8) != 0 ||
940 ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
941 r = SSH_ERR_LIBCRYPTO_ERROR;
942 goto out;
943 }
944 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
945 r = 0;
946 out:
947 ssh_digest_free(hashctx);
948 explicit_bzero(hbuf, sizeof(hbuf));
949 explicit_bzero(sbuf, sizeof(sbuf));
950 explicit_bzero(obuf, sizeof(obuf));
951 return r;
952 }
953 #endif
954
955 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
956 void
dump_digest(char * msg,u_char * digest,int len)957 dump_digest(char *msg, u_char *digest, int len)
958 {
959 fprintf(stderr, "%s\n", msg);
960 sshbuf_dump_data(digest, len, stderr);
961 }
962 #endif
963
964
965