Mercurial > dropbear
comparison common-kex.c @ 297:79bf1023cf11 agent-client
propagate from branch 'au.asn.ucc.matt.dropbear' (head 0501e6f661b5415eb76f3b312d183c3adfbfb712)
to branch 'au.asn.ucc.matt.dropbear.cli-agent' (head 01038174ec27245b51bd43a66c01ad930880f67b)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 21 Mar 2006 16:20:59 +0000 |
parents | 63601217f5ab |
children | 64abb124763d 3e098639b05f 0e69e948caba |
comparison
equal
deleted
inserted
replaced
225:ca7e76d981d9 | 297:79bf1023cf11 |
---|---|
33 #include "packet.h" | 33 #include "packet.h" |
34 #include "bignum.h" | 34 #include "bignum.h" |
35 #include "random.h" | 35 #include "random.h" |
36 | 36 |
37 /* diffie-hellman-group1-sha1 value for p */ | 37 /* diffie-hellman-group1-sha1 value for p */ |
38 const unsigned char dh_p_val[] = { | 38 static const unsigned char dh_p_val[] = { |
39 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, | 39 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, |
40 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, | 40 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, |
41 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, | 41 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, |
42 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, | 42 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, |
43 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, | 43 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, |
45 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, | 45 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, |
46 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, | 46 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, |
47 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, | 47 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, |
48 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, | 48 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, |
49 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 49 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
50 | 50 #define DH_P_LEN sizeof(dh_p_val) |
51 const int DH_G_VAL = 2; | 51 |
52 static const int DH_G_VAL = 2; | |
52 | 53 |
53 static void kexinitialise(); | 54 static void kexinitialise(); |
54 void gen_new_keys(); | 55 void gen_new_keys(); |
55 #ifndef DISABLE_ZLIB | 56 #ifndef DISABLE_ZLIB |
56 static void gen_new_zstreams(); | 57 static void gen_new_zstreams(); |
391 | 392 |
392 /* Originally from kex.c, generalized for cli/svr mode --mihnea */ | 393 /* Originally from kex.c, generalized for cli/svr mode --mihnea */ |
393 /* Belongs in common_kex.c where it should be moved after review */ | 394 /* Belongs in common_kex.c where it should be moved after review */ |
394 void recv_msg_kexinit() { | 395 void recv_msg_kexinit() { |
395 | 396 |
397 unsigned int kexhashbuf_len = 0; | |
398 unsigned int remote_ident_len = 0; | |
399 unsigned int local_ident_len = 0; | |
400 | |
396 TRACE(("<- KEXINIT")) | 401 TRACE(("<- KEXINIT")) |
397 TRACE(("enter recv_msg_kexinit")) | 402 TRACE(("enter recv_msg_kexinit")) |
398 | 403 |
399 /* start the kex hash */ | |
400 ses.kexhashbuf = buf_new(MAX_KEXHASHBUF); | |
401 | |
402 if (!ses.kexstate.sentkexinit) { | 404 if (!ses.kexstate.sentkexinit) { |
403 /* we need to send a kex packet */ | 405 /* we need to send a kex packet */ |
404 send_msg_kexinit(); | 406 send_msg_kexinit(); |
405 TRACE(("continue recv_msg_kexinit: sent kexinit")) | 407 TRACE(("continue recv_msg_kexinit: sent kexinit")) |
406 } | 408 } |
407 | 409 |
410 /* start the kex hash */ | |
411 local_ident_len = strlen(LOCAL_IDENT); | |
412 remote_ident_len = strlen((char*)ses.remoteident); | |
413 | |
414 kexhashbuf_len = local_ident_len + remote_ident_len | |
415 + ses.transkexinit->len + ses.payload->len | |
416 + KEXHASHBUF_MAX_INTS; | |
417 | |
418 ses.kexhashbuf = buf_new(kexhashbuf_len); | |
408 | 419 |
409 if (IS_DROPBEAR_CLIENT) { | 420 if (IS_DROPBEAR_CLIENT) { |
410 | 421 |
411 /* read the peer's choice of algos */ | 422 /* read the peer's choice of algos */ |
412 read_kex_algos(); | 423 read_kex_algos(); |
413 | 424 |
414 /* V_C, the client's version string (CR and NL excluded) */ | 425 /* V_C, the client's version string (CR and NL excluded) */ |
415 buf_putstring(ses.kexhashbuf, | 426 buf_putstring(ses.kexhashbuf, |
416 (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); | 427 (unsigned char*)LOCAL_IDENT, local_ident_len); |
417 /* V_S, the server's version string (CR and NL excluded) */ | 428 /* V_S, the server's version string (CR and NL excluded) */ |
418 buf_putstring(ses.kexhashbuf, | 429 buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); |
419 ses.remoteident, strlen((char*)ses.remoteident)); | |
420 | 430 |
421 /* I_C, the payload of the client's SSH_MSG_KEXINIT */ | 431 /* I_C, the payload of the client's SSH_MSG_KEXINIT */ |
422 buf_putstring(ses.kexhashbuf, | 432 buf_putstring(ses.kexhashbuf, |
423 buf_getptr(ses.transkexinit, ses.transkexinit->len), | 433 ses.transkexinit->data, ses.transkexinit->len); |
424 ses.transkexinit->len); | |
425 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ | 434 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ |
426 buf_setpos(ses.payload, 0); | 435 buf_setpos(ses.payload, 0); |
427 buf_putstring(ses.kexhashbuf, | 436 buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len); |
428 buf_getptr(ses.payload, ses.payload->len), | |
429 ses.payload->len); | |
430 | 437 |
431 } else { | 438 } else { |
432 /* SERVER */ | 439 /* SERVER */ |
433 | 440 |
434 /* read the peer's choice of algos */ | 441 /* read the peer's choice of algos */ |
435 read_kex_algos(); | 442 read_kex_algos(); |
436 /* V_C, the client's version string (CR and NL excluded) */ | 443 /* V_C, the client's version string (CR and NL excluded) */ |
444 buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); | |
445 /* V_S, the server's version string (CR and NL excluded) */ | |
437 buf_putstring(ses.kexhashbuf, | 446 buf_putstring(ses.kexhashbuf, |
438 ses.remoteident, strlen((char*)ses.remoteident)); | 447 (unsigned char*)LOCAL_IDENT, local_ident_len); |
439 /* V_S, the server's version string (CR and NL excluded) */ | |
440 buf_putstring(ses.kexhashbuf, | |
441 (unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT)); | |
442 | 448 |
443 /* I_C, the payload of the client's SSH_MSG_KEXINIT */ | 449 /* I_C, the payload of the client's SSH_MSG_KEXINIT */ |
444 buf_setpos(ses.payload, 0); | 450 buf_setpos(ses.payload, 0); |
445 buf_putstring(ses.kexhashbuf, | 451 buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len); |
446 buf_getptr(ses.payload, ses.payload->len), | 452 |
447 ses.payload->len); | |
448 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ | 453 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ |
449 buf_putstring(ses.kexhashbuf, | 454 buf_putstring(ses.kexhashbuf, |
450 buf_getptr(ses.transkexinit, ses.transkexinit->len), | 455 ses.transkexinit->data, ses.transkexinit->len); |
451 ses.transkexinit->len); | 456 |
452 ses.requirenext = SSH_MSG_KEXDH_INIT; | 457 ses.requirenext = SSH_MSG_KEXDH_INIT; |
453 } | 458 } |
454 | 459 |
455 buf_free(ses.transkexinit); | 460 buf_free(ses.transkexinit); |
456 ses.transkexinit = NULL; | 461 ses.transkexinit = NULL; |
619 c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); | 624 c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); |
620 if (c2s_cipher_algo == NULL) { | 625 if (c2s_cipher_algo == NULL) { |
621 erralgo = "enc c->s"; | 626 erralgo = "enc c->s"; |
622 goto error; | 627 goto error; |
623 } | 628 } |
624 TRACE(("c2s is %s", c2s_cipher_algo->name)) | 629 TRACE(("enc c2s is %s", c2s_cipher_algo->name)) |
625 | 630 |
626 /* encryption_algorithms_server_to_client */ | 631 /* encryption_algorithms_server_to_client */ |
627 s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); | 632 s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); |
628 if (s2c_cipher_algo == NULL) { | 633 if (s2c_cipher_algo == NULL) { |
629 erralgo = "enc s->c"; | 634 erralgo = "enc s->c"; |
630 goto error; | 635 goto error; |
631 } | 636 } |
632 TRACE(("s2c is %s", s2c_cipher_algo->name)) | 637 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) |
633 | 638 |
634 /* mac_algorithms_client_to_server */ | 639 /* mac_algorithms_client_to_server */ |
635 c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); | 640 c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); |
636 if (c2s_hash_algo == NULL) { | 641 if (c2s_hash_algo == NULL) { |
637 erralgo = "mac c->s"; | 642 erralgo = "mac c->s"; |
638 goto error; | 643 goto error; |
639 } | 644 } |
645 TRACE(("hash c2s is %s", c2s_hash_algo->name)) | |
640 | 646 |
641 /* mac_algorithms_server_to_client */ | 647 /* mac_algorithms_server_to_client */ |
642 s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); | 648 s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); |
643 if (s2c_hash_algo == NULL) { | 649 if (s2c_hash_algo == NULL) { |
644 erralgo = "mac s->c"; | 650 erralgo = "mac s->c"; |
645 goto error; | 651 goto error; |
646 } | 652 } |
653 TRACE(("hash s2c is %s", s2c_hash_algo->name)) | |
647 | 654 |
648 /* compression_algorithms_client_to_server */ | 655 /* compression_algorithms_client_to_server */ |
649 c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); | 656 c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); |
650 if (c2s_comp_algo == NULL) { | 657 if (c2s_comp_algo == NULL) { |
651 erralgo = "comp c->s"; | 658 erralgo = "comp c->s"; |
652 goto error; | 659 goto error; |
653 } | 660 } |
661 TRACE(("hash c2s is %s", c2s_comp_algo->name)) | |
654 | 662 |
655 /* compression_algorithms_server_to_client */ | 663 /* compression_algorithms_server_to_client */ |
656 s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); | 664 s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); |
657 if (s2c_comp_algo == NULL) { | 665 if (s2c_comp_algo == NULL) { |
658 erralgo = "comp s->c"; | 666 erralgo = "comp s->c"; |
659 goto error; | 667 goto error; |
660 } | 668 } |
669 TRACE(("hash s2c is %s", s2c_comp_algo->name)) | |
661 | 670 |
662 /* languages_client_to_server */ | 671 /* languages_client_to_server */ |
663 buf_eatstring(ses.payload); | 672 buf_eatstring(ses.payload); |
664 | 673 |
665 /* languages_server_to_client */ | 674 /* languages_server_to_client */ |
698 (struct dropbear_hash*)s2c_hash_algo->data; | 707 (struct dropbear_hash*)s2c_hash_algo->data; |
699 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; | 708 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; |
700 ses.newkeys->trans_algo_comp = s2c_comp_algo->val; | 709 ses.newkeys->trans_algo_comp = s2c_comp_algo->val; |
701 } | 710 } |
702 | 711 |
703 TRACE(("enc algo recv %s", algo->name)) | |
704 TRACE(("enc algo trans %s", algo->name)) | |
705 TRACE(("mac algo recv %s", algo->name)) | |
706 TRACE(("mac algo trans %s", algo->name)) | |
707 TRACE(("comp algo recv %s", algo->name)) | |
708 TRACE(("comp algo trans %s", algo->name)) | |
709 | |
710 /* reserved for future extensions */ | 712 /* reserved for future extensions */ |
711 buf_getint(ses.payload); | 713 buf_getint(ses.payload); |
712 return; | 714 return; |
713 | 715 |
714 error: | 716 error: |