Mercurial > dropbear
comparison common-kex.c @ 511:582cb38e4eb5 insecure-nocrypto
propagate from branch 'au.asn.ucc.matt.dropbear' (head cdcc3c729e29544e8b98a408e2dc60e4483dfd2a)
to branch 'au.asn.ucc.matt.dropbear.insecure-nocrypto' (head 0ca38a1cf349f7426ac9de34ebe4c3e3735effab)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 06 Nov 2008 13:16:55 +0000 |
parents | 64abb124763d 43bbe17d6ba0 |
children | 0129fd8ccc71 |
comparison
equal
deleted
inserted
replaced
361:461c4b1fb35f | 511:582cb38e4eb5 |
---|---|
186 } | 186 } |
187 | 187 |
188 /* Reset the kex state, ready for a new negotiation */ | 188 /* Reset the kex state, ready for a new negotiation */ |
189 static void kexinitialise() { | 189 static void kexinitialise() { |
190 | 190 |
191 struct timeval tv; | |
192 | |
193 TRACE(("kexinitialise()")) | 191 TRACE(("kexinitialise()")) |
194 | 192 |
195 /* sent/recv'd MSG_KEXINIT */ | 193 /* sent/recv'd MSG_KEXINIT */ |
196 ses.kexstate.sentkexinit = 0; | 194 ses.kexstate.sentkexinit = 0; |
197 ses.kexstate.recvkexinit = 0; | 195 ses.kexstate.recvkexinit = 0; |
204 ses.kexstate.firstfollows = 0; | 202 ses.kexstate.firstfollows = 0; |
205 | 203 |
206 ses.kexstate.datatrans = 0; | 204 ses.kexstate.datatrans = 0; |
207 ses.kexstate.datarecv = 0; | 205 ses.kexstate.datarecv = 0; |
208 | 206 |
209 if (gettimeofday(&tv, 0) < 0) { | 207 ses.kexstate.lastkextime = time(NULL); |
210 dropbear_exit("Error getting time"); | |
211 } | |
212 ses.kexstate.lastkextime = tv.tv_sec; | |
213 | 208 |
214 } | 209 } |
215 | 210 |
216 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the | 211 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the |
217 * already initialised hash_state hs, which should already have processed | 212 * already initialised hash_state hs, which should already have processed |
218 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. | 213 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. |
219 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. | 214 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. |
220 * The output will only be expanded once, since that is all that is required | 215 * The output will only be expanded once, as we are assured that |
221 * (for 3DES and SHA, with 24 and 20 bytes respectively). | 216 * outlen <= 2*SHA1_HASH_SIZE for all known hashes. |
222 * | 217 * |
223 * See Section 5.2 of the IETF secsh Transport Draft for details */ | 218 * See Section 7.2 of rfc4253 (ssh transport) for details */ |
224 | |
225 /* Duplicated verbatim from kex.c --mihnea */ | |
226 static void hashkeys(unsigned char *out, int outlen, | 219 static void hashkeys(unsigned char *out, int outlen, |
227 const hash_state * hs, const unsigned char X) { | 220 const hash_state * hs, const unsigned char X) { |
228 | 221 |
229 hash_state hs2; | 222 hash_state hs2; |
230 unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */ | 223 unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */ |
260 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; | 253 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; |
261 | 254 |
262 hash_state hs; | 255 hash_state hs; |
263 unsigned int C2S_keysize, S2C_keysize; | 256 unsigned int C2S_keysize, S2C_keysize; |
264 char mactransletter, macrecvletter; /* Client or server specific */ | 257 char mactransletter, macrecvletter; /* Client or server specific */ |
258 int recv_cipher = 0, trans_cipher = 0; | |
265 | 259 |
266 TRACE(("enter gen_new_keys")) | 260 TRACE(("enter gen_new_keys")) |
267 /* the dh_K and hash are the start of all hashes, we make use of that */ | 261 /* the dh_K and hash are the start of all hashes, we make use of that */ |
268 | 262 |
269 sha1_init(&hs); | 263 sha1_init(&hs); |
296 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); | 290 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); |
297 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); | 291 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); |
298 hashkeys(C2S_key, C2S_keysize, &hs, 'C'); | 292 hashkeys(C2S_key, C2S_keysize, &hs, 'C'); |
299 hashkeys(S2C_key, S2C_keysize, &hs, 'D'); | 293 hashkeys(S2C_key, S2C_keysize, &hs, 'D'); |
300 | 294 |
295 recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name); | |
296 if (recv_cipher < 0) | |
297 dropbear_exit("crypto error"); | |
298 if (ses.newkeys->recv_crypt_mode->start(recv_cipher, | |
299 recv_IV, recv_key, | |
300 ses.newkeys->recv_algo_crypt->keysize, 0, | |
301 &ses.newkeys->recv_cipher_state) != CRYPT_OK) { | |
302 dropbear_exit("crypto error"); | |
303 } | |
304 | |
305 trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name); | |
306 if (trans_cipher < 0) | |
307 dropbear_exit("crypto error"); | |
308 if (ses.newkeys->trans_crypt_mode->start(trans_cipher, | |
309 trans_IV, trans_key, | |
310 ses.newkeys->trans_algo_crypt->keysize, 0, | |
311 &ses.newkeys->trans_cipher_state) != CRYPT_OK) { | |
312 dropbear_exit("crypto error"); | |
301 if (ses.newkeys->recv_algo_crypt->cipherdesc != NULL) { | 313 if (ses.newkeys->recv_algo_crypt->cipherdesc != NULL) { |
302 if (cbc_start( | 314 if (cbc_start( |
303 find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name), | 315 find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name), |
304 recv_IV, recv_key, | 316 recv_IV, recv_key, |
305 ses.newkeys->recv_algo_crypt->keysize, 0, | 317 ses.newkeys->recv_algo_crypt->keysize, 0, |
340 | 352 |
341 TRACE(("leave gen_new_keys")) | 353 TRACE(("leave gen_new_keys")) |
342 } | 354 } |
343 | 355 |
344 #ifndef DISABLE_ZLIB | 356 #ifndef DISABLE_ZLIB |
357 | |
358 int is_compress_trans() { | |
359 return ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB | |
360 || (ses.authstate.authdone | |
361 && ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY); | |
362 } | |
363 | |
364 int is_compress_recv() { | |
365 return ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB | |
366 || (ses.authstate.authdone | |
367 && ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY); | |
368 } | |
369 | |
345 /* Set up new zlib compression streams, close the old ones. Only | 370 /* Set up new zlib compression streams, close the old ones. Only |
346 * called from gen_new_keys() */ | 371 * called from gen_new_keys() */ |
347 static void gen_new_zstreams() { | 372 static void gen_new_zstreams() { |
348 | 373 |
349 /* create new zstreams */ | 374 /* create new zstreams */ |
350 if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB) { | 375 if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB |
376 || ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { | |
351 ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream)); | 377 ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream)); |
352 ses.newkeys->recv_zstream->zalloc = Z_NULL; | 378 ses.newkeys->recv_zstream->zalloc = Z_NULL; |
353 ses.newkeys->recv_zstream->zfree = Z_NULL; | 379 ses.newkeys->recv_zstream->zfree = Z_NULL; |
354 | 380 |
355 if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) { | 381 if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) { |
357 } | 383 } |
358 } else { | 384 } else { |
359 ses.newkeys->recv_zstream = NULL; | 385 ses.newkeys->recv_zstream = NULL; |
360 } | 386 } |
361 | 387 |
362 if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB) { | 388 if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB |
389 || ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { | |
363 ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream)); | 390 ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream)); |
364 ses.newkeys->trans_zstream->zalloc = Z_NULL; | 391 ses.newkeys->trans_zstream->zalloc = Z_NULL; |
365 ses.newkeys->trans_zstream->zfree = Z_NULL; | 392 ses.newkeys->trans_zstream->zfree = Z_NULL; |
366 | 393 |
367 if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) | 394 if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) |
369 dropbear_exit("zlib error"); | 396 dropbear_exit("zlib error"); |
370 } | 397 } |
371 } else { | 398 } else { |
372 ses.newkeys->trans_zstream = NULL; | 399 ses.newkeys->trans_zstream = NULL; |
373 } | 400 } |
374 | 401 |
375 /* clean up old keys */ | 402 /* clean up old keys */ |
376 if (ses.keys->recv_zstream != NULL) { | 403 if (ses.keys->recv_zstream != NULL) { |
377 if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) { | 404 if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) { |
378 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ | 405 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ |
379 dropbear_exit("crypto error"); | 406 dropbear_exit("crypto error"); |
386 dropbear_exit("crypto error"); | 413 dropbear_exit("crypto error"); |
387 } | 414 } |
388 m_free(ses.keys->trans_zstream); | 415 m_free(ses.keys->trans_zstream); |
389 } | 416 } |
390 } | 417 } |
391 #endif | 418 #endif /* DISABLE_ZLIB */ |
392 | 419 |
393 | 420 |
394 /* Executed upon receiving a kexinit message from the client to initiate | 421 /* Executed upon receiving a kexinit message from the client to initiate |
395 * key exchange. If we haven't already done so, we send the list of our | 422 * key exchange. If we haven't already done so, we send the list of our |
396 * preferred algorithms. The client's requested algorithms are processed, | 423 * preferred algorithms. The client's requested algorithms are processed, |
523 mp_int dh_p; | 550 mp_int dh_p; |
524 mp_int *dh_e = NULL, *dh_f = NULL; | 551 mp_int *dh_e = NULL, *dh_f = NULL; |
525 hash_state hs; | 552 hash_state hs; |
526 | 553 |
527 /* read the prime and generator*/ | 554 /* read the prime and generator*/ |
528 mp_init(&dh_p); | 555 m_mp_init(&dh_p); |
529 bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); | 556 bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); |
530 | 557 |
531 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ | 558 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ |
532 if (mp_cmp(dh_pub_them, &dh_p) != MP_LT | 559 if (mp_cmp(dh_pub_them, &dh_p) != MP_LT |
533 || mp_cmp_d(dh_pub_them, 0) != MP_GT) { | 560 || mp_cmp_d(dh_pub_them, 0) != MP_GT) { |
695 if (IS_DROPBEAR_CLIENT) { | 722 if (IS_DROPBEAR_CLIENT) { |
696 ses.newkeys->recv_algo_crypt = | 723 ses.newkeys->recv_algo_crypt = |
697 (struct dropbear_cipher*)s2c_cipher_algo->data; | 724 (struct dropbear_cipher*)s2c_cipher_algo->data; |
698 ses.newkeys->trans_algo_crypt = | 725 ses.newkeys->trans_algo_crypt = |
699 (struct dropbear_cipher*)c2s_cipher_algo->data; | 726 (struct dropbear_cipher*)c2s_cipher_algo->data; |
727 ses.newkeys->recv_crypt_mode = | |
728 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; | |
729 ses.newkeys->trans_crypt_mode = | |
730 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; | |
700 ses.newkeys->recv_algo_mac = | 731 ses.newkeys->recv_algo_mac = |
701 (struct dropbear_hash*)s2c_hash_algo->data; | 732 (struct dropbear_hash*)s2c_hash_algo->data; |
702 ses.newkeys->trans_algo_mac = | 733 ses.newkeys->trans_algo_mac = |
703 (struct dropbear_hash*)c2s_hash_algo->data; | 734 (struct dropbear_hash*)c2s_hash_algo->data; |
704 ses.newkeys->recv_algo_comp = s2c_comp_algo->val; | 735 ses.newkeys->recv_algo_comp = s2c_comp_algo->val; |
707 /* SERVER */ | 738 /* SERVER */ |
708 ses.newkeys->recv_algo_crypt = | 739 ses.newkeys->recv_algo_crypt = |
709 (struct dropbear_cipher*)c2s_cipher_algo->data; | 740 (struct dropbear_cipher*)c2s_cipher_algo->data; |
710 ses.newkeys->trans_algo_crypt = | 741 ses.newkeys->trans_algo_crypt = |
711 (struct dropbear_cipher*)s2c_cipher_algo->data; | 742 (struct dropbear_cipher*)s2c_cipher_algo->data; |
743 ses.newkeys->recv_crypt_mode = | |
744 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; | |
745 ses.newkeys->trans_crypt_mode = | |
746 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; | |
712 ses.newkeys->recv_algo_mac = | 747 ses.newkeys->recv_algo_mac = |
713 (struct dropbear_hash*)c2s_hash_algo->data; | 748 (struct dropbear_hash*)c2s_hash_algo->data; |
714 ses.newkeys->trans_algo_mac = | 749 ses.newkeys->trans_algo_mac = |
715 (struct dropbear_hash*)s2c_hash_algo->data; | 750 (struct dropbear_hash*)s2c_hash_algo->data; |
716 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; | 751 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; |