Mercurial > dropbear
comparison common-kex.c @ 773:a9f2a6ae4eb5
merge
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 14 Apr 2013 22:49:19 +0800 |
parents | a389a2a7aa96 |
children | 2f1c199b6e4b |
comparison
equal
deleted
inserted
replaced
772:7fc0aeada79c | 773:a9f2a6ae4eb5 |
---|---|
78 | 78 |
79 /* Same for group1 and group14 */ | 79 /* Same for group1 and group14 */ |
80 static const int DH_G_VAL = 2; | 80 static const int DH_G_VAL = 2; |
81 | 81 |
82 static void kexinitialise(); | 82 static void kexinitialise(); |
83 void gen_new_keys(); | 83 static void gen_new_keys(); |
84 #ifndef DISABLE_ZLIB | 84 #ifndef DISABLE_ZLIB |
85 static void gen_new_zstreams(); | 85 static void gen_new_zstream_recv(); |
86 static void gen_new_zstream_trans(); | |
86 #endif | 87 #endif |
87 static void read_kex_algos(); | 88 static void read_kex_algos(); |
88 /* helper function for gen_new_keys */ | 89 /* helper function for gen_new_keys */ |
89 static void hashkeys(unsigned char *out, int outlen, | 90 static void hashkeys(unsigned char *out, int outlen, |
90 const hash_state * hs, unsigned const char X); | 91 const hash_state * hs, unsigned const char X); |
129 buf_putstring(ses.writepayload, "", 0); | 130 buf_putstring(ses.writepayload, "", 0); |
130 | 131 |
131 /* languages_server_to_client */ | 132 /* languages_server_to_client */ |
132 buf_putstring(ses.writepayload, "", 0); | 133 buf_putstring(ses.writepayload, "", 0); |
133 | 134 |
134 /* first_kex_packet_follows - unimplemented for now */ | 135 /* first_kex_packet_follows */ |
135 buf_putbyte(ses.writepayload, 0x00); | 136 buf_putbyte(ses.writepayload, (ses.send_kex_first_guess != NULL)); |
136 | 137 |
137 /* reserved unit32 */ | 138 /* reserved unit32 */ |
138 buf_putint(ses.writepayload, 0); | 139 buf_putint(ses.writepayload, 0); |
139 | 140 |
140 /* set up transmitted kex packet buffer for hashing. | 141 /* set up transmitted kex packet buffer for hashing. |
142 ses.transkexinit = buf_newcopy(ses.writepayload); | 143 ses.transkexinit = buf_newcopy(ses.writepayload); |
143 | 144 |
144 encrypt_packet(); | 145 encrypt_packet(); |
145 ses.dataallowed = 0; /* don't send other packets during kex */ | 146 ses.dataallowed = 0; /* don't send other packets during kex */ |
146 | 147 |
148 ses.kexstate.sentkexinit = 1; | |
149 | |
150 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); | |
151 | |
152 if (ses.send_kex_first_guess) { | |
153 ses.newkeys->algo_kex = sshkex[0].val; | |
154 ses.newkeys->algo_hostkey = sshhostkey[0].val; | |
155 ses.send_kex_first_guess(); | |
156 } | |
157 | |
147 TRACE(("DATAALLOWED=0")) | 158 TRACE(("DATAALLOWED=0")) |
148 TRACE(("-> KEXINIT")) | 159 TRACE(("-> KEXINIT")) |
149 ses.kexstate.sentkexinit = 1; | 160 |
150 } | 161 } |
151 | 162 |
152 /* *** NOTE regarding (send|recv)_msg_newkeys *** | 163 static void switch_keys() { |
153 * Changed by mihnea from the original kex.c to set dataallowed after a | 164 TRACE2(("enter switch_keys")) |
154 * completed key exchange, no matter the order in which it was performed. | 165 if (!(ses.kexstate.sentkexinit && ses.kexstate.recvkexinit)) { |
155 * This enables client mode without affecting server functionality. | 166 dropbear_exit("Unexpected newkeys message"); |
156 */ | 167 } |
168 | |
169 if (!ses.keys) { | |
170 ses.keys = m_malloc(sizeof(*ses.newkeys)); | |
171 } | |
172 if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) { | |
173 TRACE(("switch_keys recv")) | |
174 gen_new_zstream_recv(); | |
175 ses.keys->recv = ses.newkeys->recv; | |
176 m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv)); | |
177 ses.newkeys->recv.valid = 0; | |
178 } | |
179 if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) { | |
180 TRACE(("switch_keys trans")) | |
181 gen_new_zstream_trans(); | |
182 ses.keys->trans = ses.newkeys->trans; | |
183 m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans)); | |
184 ses.newkeys->trans.valid = 0; | |
185 } | |
186 if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys) | |
187 { | |
188 TRACE(("switch_keys done")) | |
189 ses.keys->algo_kex = ses.newkeys->algo_kex; | |
190 ses.keys->algo_hostkey = ses.newkeys->algo_hostkey; | |
191 ses.keys->allow_compress = 0; | |
192 m_free(ses.newkeys); | |
193 ses.newkeys = NULL; | |
194 kexinitialise(); | |
195 } | |
196 TRACE2(("leave switch_keys")) | |
197 } | |
157 | 198 |
158 /* Bring new keys into use after a key exchange, and let the client know*/ | 199 /* Bring new keys into use after a key exchange, and let the client know*/ |
159 void send_msg_newkeys() { | 200 void send_msg_newkeys() { |
160 | 201 |
161 TRACE(("enter send_msg_newkeys")) | 202 TRACE(("enter send_msg_newkeys")) |
162 | 203 |
163 /* generate the kexinit request */ | 204 /* generate the kexinit request */ |
164 CHECKCLEARTOWRITE(); | 205 CHECKCLEARTOWRITE(); |
165 buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS); | 206 buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS); |
166 encrypt_packet(); | 207 encrypt_packet(); |
208 | |
167 | 209 |
168 | |
169 /* set up our state */ | 210 /* set up our state */ |
170 if (ses.kexstate.recvnewkeys) { | 211 ses.kexstate.sentnewkeys = 1; |
171 TRACE(("while RECVNEWKEYS=1")) | 212 ses.kexstate.donefirstkex = 1; |
172 gen_new_keys(); | 213 ses.dataallowed = 1; /* we can send other packets again now */ |
173 kexinitialise(); /* we've finished with this kex */ | 214 gen_new_keys(); |
174 TRACE((" -> DATAALLOWED=1")) | 215 switch_keys(); |
175 ses.dataallowed = 1; /* we can send other packets again now */ | 216 |
176 ses.kexstate.donefirstkex = 1; | |
177 } else { | |
178 ses.kexstate.sentnewkeys = 1; | |
179 TRACE(("SENTNEWKEYS=1")) | |
180 } | |
181 | |
182 TRACE(("-> MSG_NEWKEYS")) | |
183 TRACE(("leave send_msg_newkeys")) | 217 TRACE(("leave send_msg_newkeys")) |
184 } | 218 } |
185 | 219 |
186 /* Bring the new keys into use after a key exchange */ | 220 /* Bring the new keys into use after a key exchange */ |
187 void recv_msg_newkeys() { | 221 void recv_msg_newkeys() { |
188 | 222 |
189 TRACE(("<- MSG_NEWKEYS")) | |
190 TRACE(("enter recv_msg_newkeys")) | 223 TRACE(("enter recv_msg_newkeys")) |
191 | 224 |
192 /* simply check if we've sent SSH_MSG_NEWKEYS, and if so, | 225 ses.kexstate.recvnewkeys = 1; |
193 * switch to the new keys */ | 226 switch_keys(); |
194 if (ses.kexstate.sentnewkeys) { | |
195 TRACE(("while SENTNEWKEYS=1")) | |
196 gen_new_keys(); | |
197 kexinitialise(); /* we've finished with this kex */ | |
198 TRACE((" -> DATAALLOWED=1")) | |
199 ses.dataallowed = 1; /* we can send other packets again now */ | |
200 ses.kexstate.donefirstkex = 1; | |
201 } else { | |
202 TRACE(("RECVNEWKEYS=1")) | |
203 ses.kexstate.recvnewkeys = 1; | |
204 } | |
205 | 227 |
206 TRACE(("leave recv_msg_newkeys")) | 228 TRACE(("leave recv_msg_newkeys")) |
207 } | 229 } |
208 | 230 |
209 | 231 |
234 /* sent/recv'd MSG_NEWKEYS */ | 256 /* sent/recv'd MSG_NEWKEYS */ |
235 ses.kexstate.recvnewkeys = 0; | 257 ses.kexstate.recvnewkeys = 0; |
236 ses.kexstate.sentnewkeys = 0; | 258 ses.kexstate.sentnewkeys = 0; |
237 | 259 |
238 /* first_packet_follows */ | 260 /* first_packet_follows */ |
239 ses.kexstate.firstfollows = 0; | 261 ses.kexstate.them_firstfollows = 0; |
240 | 262 |
241 ses.kexstate.datatrans = 0; | 263 ses.kexstate.datatrans = 0; |
242 ses.kexstate.datarecv = 0; | 264 ses.kexstate.datarecv = 0; |
265 | |
266 ses.kexstate.our_first_follows_matches = 0; | |
243 | 267 |
244 ses.kexstate.lastkextime = time(NULL); | 268 ses.kexstate.lastkextime = time(NULL); |
245 | 269 |
246 } | 270 } |
247 | 271 |
279 * This occurs after the DH key-exchange. | 303 * This occurs after the DH key-exchange. |
280 * | 304 * |
281 * ses.newkeys is the new set of keys which are generated, these are only | 305 * ses.newkeys is the new set of keys which are generated, these are only |
282 * taken into use after both sides have sent a newkeys message */ | 306 * taken into use after both sides have sent a newkeys message */ |
283 | 307 |
284 /* Originally from kex.c, generalized for cli/svr mode --mihnea */ | 308 static void gen_new_keys() { |
285 void gen_new_keys() { | |
286 | 309 |
287 unsigned char C2S_IV[MAX_IV_LEN]; | 310 unsigned char C2S_IV[MAX_IV_LEN]; |
288 unsigned char C2S_key[MAX_KEY_LEN]; | 311 unsigned char C2S_key[MAX_KEY_LEN]; |
289 unsigned char S2C_IV[MAX_IV_LEN]; | 312 unsigned char S2C_IV[MAX_IV_LEN]; |
290 unsigned char S2C_key[MAX_KEY_LEN]; | 313 unsigned char S2C_key[MAX_KEY_LEN]; |
364 hashkeys(ses.newkeys->recv.mackey, | 387 hashkeys(ses.newkeys->recv.mackey, |
365 ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter); | 388 ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter); |
366 ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hashdesc->name); | 389 ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hashdesc->name); |
367 } | 390 } |
368 | 391 |
369 #ifndef DISABLE_ZLIB | 392 /* Ready to switch over */ |
370 gen_new_zstreams(); | 393 ses.newkeys->trans.valid = 1; |
371 #endif | 394 ses.newkeys->recv.valid = 1; |
372 | |
373 /* Switch over to the new keys */ | |
374 m_burn(ses.keys, sizeof(struct key_context)); | |
375 m_free(ses.keys); | |
376 ses.keys = ses.newkeys; | |
377 ses.newkeys = NULL; | |
378 | 395 |
379 m_burn(C2S_IV, sizeof(C2S_IV)); | 396 m_burn(C2S_IV, sizeof(C2S_IV)); |
380 m_burn(C2S_key, sizeof(C2S_key)); | 397 m_burn(C2S_key, sizeof(C2S_key)); |
381 m_burn(S2C_IV, sizeof(S2C_IV)); | 398 m_burn(S2C_IV, sizeof(S2C_IV)); |
382 m_burn(S2C_key, sizeof(S2C_key)); | 399 m_burn(S2C_key, sizeof(S2C_key)); |
398 && ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY); | 415 && ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY); |
399 } | 416 } |
400 | 417 |
401 /* Set up new zlib compression streams, close the old ones. Only | 418 /* Set up new zlib compression streams, close the old ones. Only |
402 * called from gen_new_keys() */ | 419 * called from gen_new_keys() */ |
403 static void gen_new_zstreams() { | 420 static void gen_new_zstream_recv() { |
404 | 421 |
405 /* create new zstreams */ | 422 /* create new zstreams */ |
406 if (ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB | 423 if (ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB |
407 || ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { | 424 || ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { |
408 ses.newkeys->recv.zstream = (z_streamp)m_malloc(sizeof(z_stream)); | 425 ses.newkeys->recv.zstream = (z_streamp)m_malloc(sizeof(z_stream)); |
413 dropbear_exit("zlib error"); | 430 dropbear_exit("zlib error"); |
414 } | 431 } |
415 } else { | 432 } else { |
416 ses.newkeys->recv.zstream = NULL; | 433 ses.newkeys->recv.zstream = NULL; |
417 } | 434 } |
435 /* clean up old keys */ | |
436 if (ses.keys->recv.zstream != NULL) { | |
437 if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) { | |
438 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ | |
439 dropbear_exit("Crypto error"); | |
440 } | |
441 m_free(ses.keys->recv.zstream); | |
442 } | |
443 } | |
444 | |
445 static void gen_new_zstream_trans() { | |
418 | 446 |
419 if (ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB | 447 if (ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB |
420 || ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { | 448 || ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { |
421 ses.newkeys->trans.zstream = (z_streamp)m_malloc(sizeof(z_stream)); | 449 ses.newkeys->trans.zstream = (z_streamp)m_malloc(sizeof(z_stream)); |
422 ses.newkeys->trans.zstream->zalloc = Z_NULL; | 450 ses.newkeys->trans.zstream->zalloc = Z_NULL; |
430 } | 458 } |
431 } else { | 459 } else { |
432 ses.newkeys->trans.zstream = NULL; | 460 ses.newkeys->trans.zstream = NULL; |
433 } | 461 } |
434 | 462 |
435 /* clean up old keys */ | |
436 if (ses.keys->recv.zstream != NULL) { | |
437 if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) { | |
438 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ | |
439 dropbear_exit("Crypto error"); | |
440 } | |
441 m_free(ses.keys->recv.zstream); | |
442 } | |
443 if (ses.keys->trans.zstream != NULL) { | 463 if (ses.keys->trans.zstream != NULL) { |
444 if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) { | 464 if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) { |
445 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ | 465 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ |
446 dropbear_exit("Crypto error"); | 466 dropbear_exit("Crypto error"); |
447 } | 467 } |
553 | 573 |
554 DEF_MP_INT(dh_p); | 574 DEF_MP_INT(dh_p); |
555 DEF_MP_INT(dh_q); | 575 DEF_MP_INT(dh_q); |
556 DEF_MP_INT(dh_g); | 576 DEF_MP_INT(dh_g); |
557 | 577 |
558 TRACE(("enter send_msg_kexdh_reply")) | 578 TRACE(("enter gen_kexdh_vals")) |
559 | 579 |
560 m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); | 580 m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); |
561 | 581 |
562 /* read the prime and generator*/ | 582 /* read the prime and generator*/ |
563 load_dh_p(&dh_p); | 583 load_dh_p(&dh_p); |
676 int allgood = 1; /* we AND this with each goodguess and see if its still | 696 int allgood = 1; /* we AND this with each goodguess and see if its still |
677 true after */ | 697 true after */ |
678 | 698 |
679 buf_incrpos(ses.payload, 16); /* start after the cookie */ | 699 buf_incrpos(ses.payload, 16); /* start after the cookie */ |
680 | 700 |
681 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); | 701 memset(ses.newkeys, 0x0, sizeof(*ses.newkeys)); |
702 | |
703 #ifdef USE_KEXGUESS2 | |
704 enum kexguess2_used kexguess2 = KEXGUESS2_LOOK; | |
705 #else | |
706 enum kexguess2_used kexguess2 = KEXGUESS2_NO; | |
707 #endif | |
682 | 708 |
683 /* kex_algorithms */ | 709 /* kex_algorithms */ |
684 algo = ses.buf_match_algo(ses.payload, sshkex, &goodguess); | 710 algo = buf_match_algo(ses.payload, sshkex, &kexguess2, &goodguess); |
685 allgood &= goodguess; | 711 allgood &= goodguess; |
686 if (algo == NULL) { | 712 if (algo == NULL || algo->val == KEXGUESS2_ALGO_ID) { |
687 erralgo = "kex"; | 713 erralgo = "kex"; |
688 goto error; | 714 goto error; |
689 } | 715 } |
716 TRACE(("kexguess2 %d", kexguess2)) | |
690 TRACE(("kex algo %s", algo->name)) | 717 TRACE(("kex algo %s", algo->name)) |
691 ses.newkeys->algo_kex = algo->val; | 718 ses.newkeys->algo_kex = algo->val; |
692 | 719 |
693 /* server_host_key_algorithms */ | 720 /* server_host_key_algorithms */ |
694 algo = ses.buf_match_algo(ses.payload, sshhostkey, &goodguess); | 721 algo = buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess); |
695 allgood &= goodguess; | 722 allgood &= goodguess; |
696 if (algo == NULL) { | 723 if (algo == NULL) { |
697 erralgo = "hostkey"; | 724 erralgo = "hostkey"; |
698 goto error; | 725 goto error; |
699 } | 726 } |
700 TRACE(("hostkey algo %s", algo->name)) | 727 TRACE(("hostkey algo %s", algo->name)) |
701 ses.newkeys->algo_hostkey = algo->val; | 728 ses.newkeys->algo_hostkey = algo->val; |
702 | 729 |
703 /* encryption_algorithms_client_to_server */ | 730 /* encryption_algorithms_client_to_server */ |
704 c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); | 731 c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL); |
705 if (c2s_cipher_algo == NULL) { | 732 if (c2s_cipher_algo == NULL) { |
706 erralgo = "enc c->s"; | 733 erralgo = "enc c->s"; |
707 goto error; | 734 goto error; |
708 } | 735 } |
709 TRACE(("enc c2s is %s", c2s_cipher_algo->name)) | 736 TRACE(("enc c2s is %s", c2s_cipher_algo->name)) |
710 | 737 |
711 /* encryption_algorithms_server_to_client */ | 738 /* encryption_algorithms_server_to_client */ |
712 s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); | 739 s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, NULL, NULL); |
713 if (s2c_cipher_algo == NULL) { | 740 if (s2c_cipher_algo == NULL) { |
714 erralgo = "enc s->c"; | 741 erralgo = "enc s->c"; |
715 goto error; | 742 goto error; |
716 } | 743 } |
717 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) | 744 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) |
718 | 745 |
719 /* mac_algorithms_client_to_server */ | 746 /* mac_algorithms_client_to_server */ |
720 c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); | 747 c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); |
721 if (c2s_hash_algo == NULL) { | 748 if (c2s_hash_algo == NULL) { |
722 erralgo = "mac c->s"; | 749 erralgo = "mac c->s"; |
723 goto error; | 750 goto error; |
724 } | 751 } |
725 TRACE(("hash c2s is %s", c2s_hash_algo->name)) | 752 TRACE(("hash c2s is %s", c2s_hash_algo->name)) |
726 | 753 |
727 /* mac_algorithms_server_to_client */ | 754 /* mac_algorithms_server_to_client */ |
728 s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); | 755 s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); |
729 if (s2c_hash_algo == NULL) { | 756 if (s2c_hash_algo == NULL) { |
730 erralgo = "mac s->c"; | 757 erralgo = "mac s->c"; |
731 goto error; | 758 goto error; |
732 } | 759 } |
733 TRACE(("hash s2c is %s", s2c_hash_algo->name)) | 760 TRACE(("hash s2c is %s", s2c_hash_algo->name)) |
734 | 761 |
735 /* compression_algorithms_client_to_server */ | 762 /* compression_algorithms_client_to_server */ |
736 c2s_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, &goodguess); | 763 c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); |
737 if (c2s_comp_algo == NULL) { | 764 if (c2s_comp_algo == NULL) { |
738 erralgo = "comp c->s"; | 765 erralgo = "comp c->s"; |
739 goto error; | 766 goto error; |
740 } | 767 } |
741 TRACE(("hash c2s is %s", c2s_comp_algo->name)) | 768 TRACE(("hash c2s is %s", c2s_comp_algo->name)) |
742 | 769 |
743 /* compression_algorithms_server_to_client */ | 770 /* compression_algorithms_server_to_client */ |
744 s2c_comp_algo = ses.buf_match_algo(ses.payload, ses.compress_algos, &goodguess); | 771 s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); |
745 if (s2c_comp_algo == NULL) { | 772 if (s2c_comp_algo == NULL) { |
746 erralgo = "comp s->c"; | 773 erralgo = "comp s->c"; |
747 goto error; | 774 goto error; |
748 } | 775 } |
749 TRACE(("hash s2c is %s", s2c_comp_algo->name)) | 776 TRACE(("hash s2c is %s", s2c_comp_algo->name)) |
752 buf_eatstring(ses.payload); | 779 buf_eatstring(ses.payload); |
753 | 780 |
754 /* languages_server_to_client */ | 781 /* languages_server_to_client */ |
755 buf_eatstring(ses.payload); | 782 buf_eatstring(ses.payload); |
756 | 783 |
757 /* first_kex_packet_follows */ | 784 /* their first_kex_packet_follows */ |
758 if (buf_getbool(ses.payload)) { | 785 if (buf_getbool(ses.payload)) { |
759 ses.kexstate.firstfollows = 1; | 786 TRACE(("them kex firstfollows. allgood %d", allgood)) |
787 ses.kexstate.them_firstfollows = 1; | |
760 /* if the guess wasn't good, we ignore the packet sent */ | 788 /* if the guess wasn't good, we ignore the packet sent */ |
761 if (!allgood) { | 789 if (!allgood) { |
762 ses.ignorenext = 1; | 790 ses.ignorenext = 1; |
763 } | 791 } |
764 } | 792 } |
797 ses.newkeys->trans.algo_comp = s2c_comp_algo->val; | 825 ses.newkeys->trans.algo_comp = s2c_comp_algo->val; |
798 } | 826 } |
799 | 827 |
800 /* reserved for future extensions */ | 828 /* reserved for future extensions */ |
801 buf_getint(ses.payload); | 829 buf_getint(ses.payload); |
830 | |
831 if (ses.send_kex_first_guess && allgood) { | |
832 TRACE(("our_first_follows_matches 1")) | |
833 ses.kexstate.our_first_follows_matches = 1; | |
834 } | |
802 return; | 835 return; |
803 | 836 |
804 error: | 837 error: |
805 dropbear_exit("No matching algo %s", erralgo); | 838 dropbear_exit("No matching algo %s", erralgo); |
806 } | 839 } |