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: