Mercurial > dropbear
comparison common-kex.c @ 753:d63ef1e211ea
Take transmit and receive keys into use separately
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 04 Apr 2013 00:18:50 +0800 |
parents | 465fefc4f6e0 |
children | a389a2a7aa96 |
comparison
equal
deleted
inserted
replaced
752:24172f555f9c | 753:d63ef1e211ea |
---|---|
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_zstreams(); |
86 #endif | 86 #endif |
87 static void read_kex_algos(); | 87 static void read_kex_algos(); |
88 /* helper function for gen_new_keys */ | 88 /* helper function for gen_new_keys */ |
157 TRACE(("DATAALLOWED=0")) | 157 TRACE(("DATAALLOWED=0")) |
158 TRACE(("-> KEXINIT")) | 158 TRACE(("-> KEXINIT")) |
159 | 159 |
160 } | 160 } |
161 | 161 |
162 /* *** NOTE regarding (send|recv)_msg_newkeys *** | 162 void switch_keys() { |
163 * Changed by mihnea from the original kex.c to set dataallowed after a | 163 TRACE2(("enter switch_keys")) |
164 * completed key exchange, no matter the order in which it was performed. | 164 if (!(ses.kexstate.sentkexinit && ses.kexstate.recvkexinit)) { |
165 * This enables client mode without affecting server functionality. | 165 dropbear_exit("Unexpected newkeys message"); |
166 */ | 166 } |
167 | |
168 if (!ses.keys) { | |
169 ses.keys = m_malloc(sizeof(*ses.newkeys)); | |
170 } | |
171 if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) { | |
172 TRACE(("switch_keys recv")) | |
173 ses.keys->recv = ses.newkeys->recv; | |
174 m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv)); | |
175 ses.newkeys->recv.valid = 0; | |
176 } | |
177 if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) { | |
178 TRACE(("switch_keys trans")) | |
179 ses.keys->trans = ses.newkeys->trans; | |
180 m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans)); | |
181 ses.newkeys->trans.valid = 0; | |
182 } | |
183 if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys) | |
184 { | |
185 TRACE(("switch_keys done")) | |
186 ses.keys->algo_kex = ses.newkeys->algo_kex; | |
187 ses.keys->algo_hostkey = ses.newkeys->algo_hostkey; | |
188 ses.keys->allow_compress = 0; | |
189 m_free(ses.newkeys); | |
190 ses.newkeys = NULL; | |
191 kexinitialise(); | |
192 } | |
193 TRACE2(("leave switch_keys")) | |
194 } | |
167 | 195 |
168 /* Bring new keys into use after a key exchange, and let the client know*/ | 196 /* Bring new keys into use after a key exchange, and let the client know*/ |
169 void send_msg_newkeys() { | 197 void send_msg_newkeys() { |
170 | 198 |
171 TRACE(("enter send_msg_newkeys")) | 199 TRACE(("enter send_msg_newkeys")) |
172 | 200 |
173 /* generate the kexinit request */ | 201 /* generate the kexinit request */ |
174 CHECKCLEARTOWRITE(); | 202 CHECKCLEARTOWRITE(); |
175 buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS); | 203 buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS); |
176 encrypt_packet(); | 204 encrypt_packet(); |
177 | 205 |
178 | 206 |
179 /* set up our state */ | 207 /* set up our state */ |
180 if (ses.kexstate.recvnewkeys) { | 208 ses.kexstate.sentnewkeys = 1; |
181 TRACE(("while RECVNEWKEYS=1")) | 209 ses.kexstate.donefirstkex = 1; |
182 gen_new_keys(); | 210 ses.dataallowed = 1; /* we can send other packets again now */ |
183 kexinitialise(); /* we've finished with this kex */ | 211 gen_new_keys(); |
184 TRACE((" -> DATAALLOWED=1")) | 212 switch_keys(); |
185 ses.dataallowed = 1; /* we can send other packets again now */ | 213 |
186 ses.kexstate.donefirstkex = 1; | |
187 } else { | |
188 ses.kexstate.sentnewkeys = 1; | |
189 TRACE(("SENTNEWKEYS=1")) | |
190 } | |
191 | |
192 TRACE(("-> MSG_NEWKEYS")) | |
193 TRACE(("leave send_msg_newkeys")) | 214 TRACE(("leave send_msg_newkeys")) |
194 } | 215 } |
195 | 216 |
196 /* Bring the new keys into use after a key exchange */ | 217 /* Bring the new keys into use after a key exchange */ |
197 void recv_msg_newkeys() { | 218 void recv_msg_newkeys() { |
198 | 219 |
199 TRACE(("<- MSG_NEWKEYS")) | |
200 TRACE(("enter recv_msg_newkeys")) | 220 TRACE(("enter recv_msg_newkeys")) |
201 | 221 |
202 /* simply check if we've sent SSH_MSG_NEWKEYS, and if so, | 222 ses.kexstate.recvnewkeys = 1; |
203 * switch to the new keys */ | 223 switch_keys(); |
204 if (ses.kexstate.sentnewkeys) { | |
205 TRACE(("while SENTNEWKEYS=1")) | |
206 gen_new_keys(); | |
207 kexinitialise(); /* we've finished with this kex */ | |
208 TRACE((" -> DATAALLOWED=1")) | |
209 ses.dataallowed = 1; /* we can send other packets again now */ | |
210 ses.kexstate.donefirstkex = 1; | |
211 } else { | |
212 TRACE(("RECVNEWKEYS=1")) | |
213 ses.kexstate.recvnewkeys = 1; | |
214 } | |
215 | 224 |
216 TRACE(("leave recv_msg_newkeys")) | 225 TRACE(("leave recv_msg_newkeys")) |
217 } | 226 } |
218 | 227 |
219 | 228 |
291 * This occurs after the DH key-exchange. | 300 * This occurs after the DH key-exchange. |
292 * | 301 * |
293 * ses.newkeys is the new set of keys which are generated, these are only | 302 * ses.newkeys is the new set of keys which are generated, these are only |
294 * taken into use after both sides have sent a newkeys message */ | 303 * taken into use after both sides have sent a newkeys message */ |
295 | 304 |
296 /* Originally from kex.c, generalized for cli/svr mode --mihnea */ | 305 static void gen_new_keys() { |
297 void gen_new_keys() { | |
298 | 306 |
299 unsigned char C2S_IV[MAX_IV_LEN]; | 307 unsigned char C2S_IV[MAX_IV_LEN]; |
300 unsigned char C2S_key[MAX_KEY_LEN]; | 308 unsigned char C2S_key[MAX_KEY_LEN]; |
301 unsigned char S2C_IV[MAX_IV_LEN]; | 309 unsigned char S2C_IV[MAX_IV_LEN]; |
302 unsigned char S2C_key[MAX_KEY_LEN]; | 310 unsigned char S2C_key[MAX_KEY_LEN]; |
380 | 388 |
381 #ifndef DISABLE_ZLIB | 389 #ifndef DISABLE_ZLIB |
382 gen_new_zstreams(); | 390 gen_new_zstreams(); |
383 #endif | 391 #endif |
384 | 392 |
385 /* Switch over to the new keys */ | 393 /* Ready to switch over */ |
386 m_burn(ses.keys, sizeof(struct key_context)); | 394 ses.newkeys->trans.valid = 1; |
387 m_free(ses.keys); | 395 ses.newkeys->recv.valid = 1; |
388 ses.keys = ses.newkeys; | |
389 ses.newkeys = NULL; | |
390 | 396 |
391 m_burn(C2S_IV, sizeof(C2S_IV)); | 397 m_burn(C2S_IV, sizeof(C2S_IV)); |
392 m_burn(C2S_key, sizeof(C2S_key)); | 398 m_burn(C2S_key, sizeof(C2S_key)); |
393 m_burn(S2C_IV, sizeof(S2C_IV)); | 399 m_burn(S2C_IV, sizeof(S2C_IV)); |
394 m_burn(S2C_key, sizeof(S2C_key)); | 400 m_burn(S2C_key, sizeof(S2C_key)); |