Mercurial > dropbear
comparison common-kex.c @ 36:a600c015562d
Handle differing c2s and s2c algorithms properly
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 29 Jul 2004 15:43:26 +0000 |
parents | 0ad5fb979f42 |
children | e3adf4cf5465 |
comparison
equal
deleted
inserted
replaced
35:0ad5fb979f42 | 36:a600c015562d |
---|---|
409 TRACE(("continue recv_msg_kexinit: sent kexinit")); | 409 TRACE(("continue recv_msg_kexinit: sent kexinit")); |
410 } | 410 } |
411 | 411 |
412 | 412 |
413 if (IS_DROPBEAR_CLIENT) { | 413 if (IS_DROPBEAR_CLIENT) { |
414 #ifdef DROPBEAR_CLIENT | |
415 | 414 |
416 /* read the peer's choice of algos */ | 415 /* read the peer's choice of algos */ |
417 read_kex_algos(); | 416 read_kex_algos(); |
418 | 417 |
419 /* V_C, the client's version string (CR and NL excluded) */ | 418 /* V_C, the client's version string (CR and NL excluded) */ |
431 buf_setpos(ses.payload, 0); | 430 buf_setpos(ses.payload, 0); |
432 buf_putstring(ses.kexhashbuf, | 431 buf_putstring(ses.kexhashbuf, |
433 buf_getptr(ses.payload, ses.payload->len), | 432 buf_getptr(ses.payload, ses.payload->len), |
434 ses.payload->len); | 433 ses.payload->len); |
435 | 434 |
436 #endif | |
437 } else { | 435 } else { |
438 /* SERVER */ | 436 /* SERVER */ |
439 #ifdef DROPBEAR_SERVER | |
440 | 437 |
441 /* read the peer's choice of algos */ | 438 /* read the peer's choice of algos */ |
442 read_kex_algos(); | 439 read_kex_algos(); |
443 /* V_C, the client's version string (CR and NL excluded) */ | 440 /* V_C, the client's version string (CR and NL excluded) */ |
444 buf_putstring(ses.kexhashbuf, | 441 buf_putstring(ses.kexhashbuf, |
455 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ | 452 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ |
456 buf_putstring(ses.kexhashbuf, | 453 buf_putstring(ses.kexhashbuf, |
457 buf_getptr(ses.transkexinit, ses.transkexinit->len), | 454 buf_getptr(ses.transkexinit, ses.transkexinit->len), |
458 ses.transkexinit->len); | 455 ses.transkexinit->len); |
459 ses.requirenext = SSH_MSG_KEXDH_INIT; | 456 ses.requirenext = SSH_MSG_KEXDH_INIT; |
460 #endif | |
461 } | 457 } |
462 | 458 |
463 buf_free(ses.transkexinit); | 459 buf_free(ses.transkexinit); |
464 ses.transkexinit = NULL; | 460 ses.transkexinit = NULL; |
465 /* the rest of ses.kexhashbuf will be done after DH exchange */ | 461 /* the rest of ses.kexhashbuf will be done after DH exchange */ |
594 | 590 |
595 /* read the other side's algo list. buf_match_algo is a callback to match | 591 /* read the other side's algo list. buf_match_algo is a callback to match |
596 * algos for the client or server. */ | 592 * algos for the client or server. */ |
597 static void read_kex_algos() { | 593 static void read_kex_algos() { |
598 | 594 |
599 algo_type * algo; | 595 /* for asymmetry */ |
596 algo_type * c2s_hash_algo = NULL; | |
597 algo_type * s2c_hash_algo = NULL; | |
598 algo_type * c2s_cipher_algo = NULL; | |
599 algo_type * s2c_cipher_algo = NULL; | |
600 algo_type * c2s_comp_algo = NULL; | |
601 algo_type * s2c_comp_algo = NULL; | |
602 /* the generic one */ | |
603 algo_type * algo = NULL; | |
604 | |
605 /* which algo couldn't match */ | |
600 char * erralgo = NULL; | 606 char * erralgo = NULL; |
601 | 607 |
602 int goodguess = 0; | 608 int goodguess = 0; |
603 int allgood = 1; /* we AND this with each goodguess and see if its still | 609 int allgood = 1; /* we AND this with each goodguess and see if its still |
604 true after */ | 610 true after */ |
626 } | 632 } |
627 TRACE(("hostkey algo %s", algo->name)); | 633 TRACE(("hostkey algo %s", algo->name)); |
628 ses.newkeys->algo_hostkey = algo->val; | 634 ses.newkeys->algo_hostkey = algo->val; |
629 | 635 |
630 /* encryption_algorithms_client_to_server */ | 636 /* encryption_algorithms_client_to_server */ |
631 algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); | 637 c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); |
632 if (algo == NULL) { | 638 if (algo == NULL) { |
633 erralgo = "enc c->s"; | 639 erralgo = "enc c->s"; |
634 goto error; | 640 goto error; |
635 } | 641 } |
636 ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; | |
637 TRACE(("enc algo recv %s", algo->name)); | |
638 | 642 |
639 /* encryption_algorithms_server_to_client */ | 643 /* encryption_algorithms_server_to_client */ |
640 algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); | 644 s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); |
641 if (algo == NULL) { | 645 if (algo == NULL) { |
642 erralgo = "enc s->c"; | 646 erralgo = "enc s->c"; |
643 goto error; | 647 goto error; |
644 } | 648 } |
645 ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; | |
646 TRACE(("enc algo trans %s", algo->name)); | |
647 | 649 |
648 /* mac_algorithms_client_to_server */ | 650 /* mac_algorithms_client_to_server */ |
649 algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); | 651 c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); |
650 if (algo == NULL) { | 652 if (algo == NULL) { |
651 erralgo = "mac c->s"; | 653 erralgo = "mac c->s"; |
652 goto error; | 654 goto error; |
653 } | 655 } |
654 ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; | |
655 TRACE(("mac algo recv %s", algo->name)); | |
656 | 656 |
657 /* mac_algorithms_server_to_client */ | 657 /* mac_algorithms_server_to_client */ |
658 algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); | 658 s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); |
659 if (algo == NULL) { | 659 if (algo == NULL) { |
660 erralgo = "mac s->c"; | 660 erralgo = "mac s->c"; |
661 goto error; | 661 goto error; |
662 } | 662 } |
663 ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; | |
664 TRACE(("mac algo trans %s", algo->name)); | |
665 | 663 |
666 /* compression_algorithms_client_to_server */ | 664 /* compression_algorithms_client_to_server */ |
667 algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); | 665 c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); |
668 if (algo == NULL) { | 666 if (algo == NULL) { |
669 erralgo = "comp c->s"; | 667 erralgo = "comp c->s"; |
670 goto error; | 668 goto error; |
671 } | 669 } |
672 ses.newkeys->recv_algo_comp = algo->val; | |
673 TRACE(("comp algo recv %s", algo->name)); | |
674 | 670 |
675 /* compression_algorithms_server_to_client */ | 671 /* compression_algorithms_server_to_client */ |
676 algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); | 672 s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); |
677 if (algo == NULL) { | 673 if (algo == NULL) { |
678 erralgo = "comp s->c"; | 674 erralgo = "comp s->c"; |
679 goto error; | 675 goto error; |
680 } | 676 } |
681 ses.newkeys->trans_algo_comp = algo->val; | |
682 TRACE(("comp algo trans %s", algo->name)); | |
683 | 677 |
684 /* languages_client_to_server */ | 678 /* languages_client_to_server */ |
685 buf_eatstring(ses.payload); | 679 buf_eatstring(ses.payload); |
686 | 680 |
687 /* languages_server_to_client */ | 681 /* languages_server_to_client */ |
694 if (!allgood) { | 688 if (!allgood) { |
695 ses.ignorenext = 1; | 689 ses.ignorenext = 1; |
696 } | 690 } |
697 } | 691 } |
698 | 692 |
693 /* Handle the asymmetry */ | |
694 if (IS_DROPBEAR_CLIENT) { | |
695 ses.newkeys->recv_algo_crypt = | |
696 (struct dropbear_cipher*)s2c_cipher_algo->data; | |
697 ses.newkeys->trans_algo_crypt = | |
698 (struct dropbear_cipher*)c2s_cipher_algo->data; | |
699 ses.newkeys->recv_algo_mac = | |
700 (struct dropbear_hash*)s2c_hash_algo->data; | |
701 ses.newkeys->trans_algo_mac = | |
702 (struct dropbear_hash*)c2s_hash_algo->data; | |
703 ses.newkeys->recv_algo_comp = s2c_comp_algo->val; | |
704 ses.newkeys->trans_algo_comp = c2s_comp_algo->val; | |
705 } else { | |
706 /* SERVER */ | |
707 ses.newkeys->recv_algo_crypt = | |
708 (struct dropbear_cipher*)c2s_cipher_algo->data; | |
709 ses.newkeys->trans_algo_crypt = | |
710 (struct dropbear_cipher*)s2c_cipher_algo->data; | |
711 ses.newkeys->recv_algo_mac = | |
712 (struct dropbear_hash*)c2s_hash_algo->data; | |
713 ses.newkeys->trans_algo_mac = | |
714 (struct dropbear_hash*)s2c_hash_algo->data; | |
715 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; | |
716 ses.newkeys->trans_algo_comp = s2c_comp_algo->val; | |
717 } | |
718 | |
719 TRACE(("enc algo recv %s", algo->name)); | |
720 TRACE(("enc algo trans %s", algo->name)); | |
721 TRACE(("mac algo recv %s", algo->name)); | |
722 TRACE(("mac algo trans %s", algo->name)); | |
723 TRACE(("comp algo recv %s", algo->name)); | |
724 TRACE(("comp algo trans %s", algo->name)); | |
725 | |
699 /* reserved for future extensions */ | 726 /* reserved for future extensions */ |
700 buf_getint(ses.payload); | 727 buf_getint(ses.payload); |
701 return; | 728 return; |
702 | 729 |
703 error: | 730 error: |