# HG changeset patch # User Matt Johnston # Date 1091115806 0 # Node ID a600c015562d7950097c4e1ab6d7534b6dffcc63 # Parent 0ad5fb979f42f67b359f3d68b72c76b064a7111b Handle differing c2s and s2c algorithms properly diff -r 0ad5fb979f42 -r a600c015562d common-kex.c --- a/common-kex.c Thu Jul 29 02:19:03 2004 +0000 +++ b/common-kex.c Thu Jul 29 15:43:26 2004 +0000 @@ -411,7 +411,6 @@ if (IS_DROPBEAR_CLIENT) { -#ifdef DROPBEAR_CLIENT /* read the peer's choice of algos */ read_kex_algos(); @@ -433,10 +432,8 @@ buf_getptr(ses.payload, ses.payload->len), ses.payload->len); -#endif } else { /* SERVER */ -#ifdef DROPBEAR_SERVER /* read the peer's choice of algos */ read_kex_algos(); @@ -457,7 +454,6 @@ buf_getptr(ses.transkexinit, ses.transkexinit->len), ses.transkexinit->len); ses.requirenext = SSH_MSG_KEXDH_INIT; -#endif } buf_free(ses.transkexinit); @@ -596,7 +592,17 @@ * algos for the client or server. */ static void read_kex_algos() { - algo_type * algo; + /* for asymmetry */ + algo_type * c2s_hash_algo = NULL; + algo_type * s2c_hash_algo = NULL; + algo_type * c2s_cipher_algo = NULL; + algo_type * s2c_cipher_algo = NULL; + algo_type * c2s_comp_algo = NULL; + algo_type * s2c_comp_algo = NULL; + /* the generic one */ + algo_type * algo = NULL; + + /* which algo couldn't match */ char * erralgo = NULL; int goodguess = 0; @@ -628,58 +634,46 @@ ses.newkeys->algo_hostkey = algo->val; /* encryption_algorithms_client_to_server */ - algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); + c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); if (algo == NULL) { erralgo = "enc c->s"; goto error; } - ses.newkeys->recv_algo_crypt = (struct dropbear_cipher*)algo->data; - TRACE(("enc algo recv %s", algo->name)); /* encryption_algorithms_server_to_client */ - algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); + s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); if (algo == NULL) { erralgo = "enc s->c"; goto error; } - ses.newkeys->trans_algo_crypt = (struct dropbear_cipher*)algo->data; - TRACE(("enc algo trans %s", algo->name)); /* mac_algorithms_client_to_server */ - algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); + c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); if (algo == NULL) { erralgo = "mac c->s"; goto error; } - ses.newkeys->recv_algo_mac = (struct dropbear_hash*)algo->data; - TRACE(("mac algo recv %s", algo->name)); /* mac_algorithms_server_to_client */ - algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); + s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); if (algo == NULL) { erralgo = "mac s->c"; goto error; } - ses.newkeys->trans_algo_mac = (struct dropbear_hash*)algo->data; - TRACE(("mac algo trans %s", algo->name)); /* compression_algorithms_client_to_server */ - algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); + c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); if (algo == NULL) { erralgo = "comp c->s"; goto error; } - ses.newkeys->recv_algo_comp = algo->val; - TRACE(("comp algo recv %s", algo->name)); /* compression_algorithms_server_to_client */ - algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); + s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); if (algo == NULL) { erralgo = "comp s->c"; goto error; } - ses.newkeys->trans_algo_comp = algo->val; - TRACE(("comp algo trans %s", algo->name)); /* languages_client_to_server */ buf_eatstring(ses.payload); @@ -696,6 +690,39 @@ } } + /* Handle the asymmetry */ + if (IS_DROPBEAR_CLIENT) { + ses.newkeys->recv_algo_crypt = + (struct dropbear_cipher*)s2c_cipher_algo->data; + ses.newkeys->trans_algo_crypt = + (struct dropbear_cipher*)c2s_cipher_algo->data; + ses.newkeys->recv_algo_mac = + (struct dropbear_hash*)s2c_hash_algo->data; + ses.newkeys->trans_algo_mac = + (struct dropbear_hash*)c2s_hash_algo->data; + ses.newkeys->recv_algo_comp = s2c_comp_algo->val; + ses.newkeys->trans_algo_comp = c2s_comp_algo->val; + } else { + /* SERVER */ + ses.newkeys->recv_algo_crypt = + (struct dropbear_cipher*)c2s_cipher_algo->data; + ses.newkeys->trans_algo_crypt = + (struct dropbear_cipher*)s2c_cipher_algo->data; + ses.newkeys->recv_algo_mac = + (struct dropbear_hash*)c2s_hash_algo->data; + ses.newkeys->trans_algo_mac = + (struct dropbear_hash*)s2c_hash_algo->data; + ses.newkeys->recv_algo_comp = c2s_comp_algo->val; + ses.newkeys->trans_algo_comp = s2c_comp_algo->val; + } + + TRACE(("enc algo recv %s", algo->name)); + TRACE(("enc algo trans %s", algo->name)); + TRACE(("mac algo recv %s", algo->name)); + TRACE(("mac algo trans %s", algo->name)); + TRACE(("comp algo recv %s", algo->name)); + TRACE(("comp algo trans %s", algo->name)); + /* reserved for future extensions */ buf_getint(ses.payload); return;