comparison cli-kex.c @ 839:33207ed1174b

Merge in ECC
author Matt Johnston <matt@ucc.asn.au>
date Mon, 21 Oct 2013 22:57:21 +0800
parents 7dcb46da72d9
children f4bb964c8678 6c69e7df3621
comparison
equal deleted inserted replaced
834:e378da7eae5d 839:33207ed1174b
34 #include "packet.h" 34 #include "packet.h"
35 #include "bignum.h" 35 #include "bignum.h"
36 #include "random.h" 36 #include "random.h"
37 #include "runopts.h" 37 #include "runopts.h"
38 #include "signkey.h" 38 #include "signkey.h"
39 #include "ecc.h"
39 40
40 41
41 static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen); 42 static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen);
42 #define MAX_KNOWNHOSTS_LINE 4500 43 #define MAX_KNOWNHOSTS_LINE 4500
43 44
44 void send_msg_kexdh_init() { 45 void send_msg_kexdh_init() {
45 TRACE(("send_msg_kexdh_init()")) 46 TRACE(("send_msg_kexdh_init()"))
46 if ((cli_ses.dh_e && cli_ses.dh_x
47 && cli_ses.dh_val_algo == ses.newkeys->algo_kex)) {
48 TRACE(("reusing existing dh_e from first_kex_packet_follows"))
49 } else {
50 if (!cli_ses.dh_e || !cli_ses.dh_e) {
51 cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
52 cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
53 m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
54 }
55
56 gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x);
57 cli_ses.dh_val_algo = ses.newkeys->algo_kex;
58 }
59 47
60 CHECKCLEARTOWRITE(); 48 CHECKCLEARTOWRITE();
61 buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT); 49 buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
62 buf_putmpint(ses.writepayload, cli_ses.dh_e); 50 if (IS_NORMAL_DH(ses.newkeys->algo_kex)) {
51 if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
52 || !cli_ses.dh_param) {
53 if (cli_ses.dh_param) {
54 free_kexdh_param(cli_ses.dh_param);
55 }
56 cli_ses.dh_param = gen_kexdh_param();
57 }
58 buf_putmpint(ses.writepayload, &cli_ses.dh_param->pub);
59 } else {
60 #ifdef DROPBEAR_ECDH
61 if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
62 || !cli_ses.ecdh_param) {
63 if (cli_ses.ecdh_param) {
64 free_kexecdh_param(cli_ses.ecdh_param);
65 }
66 cli_ses.ecdh_param = gen_kexecdh_param();
67 }
68 buf_put_ecc_raw_pubkey_string(ses.writepayload, &cli_ses.ecdh_param->key);
69 #endif
70 }
71 cli_ses.param_kex_algo = ses.newkeys->algo_kex;
63 encrypt_packet(); 72 encrypt_packet();
64 ses.requirenext[0] = SSH_MSG_KEXDH_REPLY; 73 ses.requirenext[0] = SSH_MSG_KEXDH_REPLY;
65 ses.requirenext[1] = SSH_MSG_KEXINIT; 74 ses.requirenext[1] = SSH_MSG_KEXINIT;
66 } 75 }
67 76
68 /* Handle a diffie-hellman key exchange reply. */ 77 /* Handle a diffie-hellman key exchange reply. */
69 void recv_msg_kexdh_reply() { 78 void recv_msg_kexdh_reply() {
70 79
71 DEF_MP_INT(dh_f);
72 sign_key *hostkey = NULL; 80 sign_key *hostkey = NULL;
73 unsigned int type, keybloblen; 81 unsigned int type, keybloblen;
74 unsigned char* keyblob = NULL; 82 unsigned char* keyblob = NULL;
75 83
76
77 TRACE(("enter recv_msg_kexdh_reply")) 84 TRACE(("enter recv_msg_kexdh_reply"))
78 85
79 if (cli_ses.kex_state != KEXDH_INIT_SENT) { 86 if (cli_ses.kex_state != KEXDH_INIT_SENT) {
80 dropbear_exit("Received out-of-order kexdhreply"); 87 dropbear_exit("Received out-of-order kexdhreply");
81 } 88 }
82 m_mp_init(&dh_f);
83 type = ses.newkeys->algo_hostkey; 89 type = ses.newkeys->algo_hostkey;
84 TRACE(("type is %d", type)) 90 TRACE(("type is %d", type))
85 91
86 hostkey = new_sign_key(); 92 hostkey = new_sign_key();
87 keybloblen = buf_getint(ses.payload); 93 keybloblen = buf_getint(ses.payload);
95 if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) { 101 if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
96 TRACE(("failed getting pubkey")) 102 TRACE(("failed getting pubkey"))
97 dropbear_exit("Bad KEX packet"); 103 dropbear_exit("Bad KEX packet");
98 } 104 }
99 105
100 if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) { 106 if (IS_NORMAL_DH(ses.newkeys->algo_kex)) {
101 TRACE(("failed getting mpint")) 107 // Normal diffie-hellman
102 dropbear_exit("Bad KEX packet"); 108 DEF_MP_INT(dh_f);
103 } 109 m_mp_init(&dh_f);
104 110 if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
105 kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey); 111 TRACE(("failed getting mpint"))
106 mp_clear(&dh_f); 112 dropbear_exit("Bad KEX packet");
107 mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); 113 }
108 m_free(cli_ses.dh_e); 114
109 m_free(cli_ses.dh_x); 115 kexdh_comb_key(cli_ses.dh_param, &dh_f, hostkey);
110 cli_ses.dh_val_algo = DROPBEAR_KEX_NONE; 116 mp_clear(&dh_f);
111 117 } else {
112 if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) 118 #ifdef DROPBEAR_ECDH
113 != DROPBEAR_SUCCESS) { 119 buffer *ecdh_qs = buf_getstringbuf(ses.payload);
120 kexecdh_comb_key(cli_ses.ecdh_param, ecdh_qs, hostkey);
121 buf_free(ecdh_qs);
122 #endif
123 }
124
125 if (cli_ses.dh_param) {
126 free_kexdh_param(cli_ses.dh_param);
127 cli_ses.dh_param = NULL;
128 }
129 #ifdef DROPBEAR_ECDH
130 if (cli_ses.ecdh_param) {
131 free_kexecdh_param(cli_ses.ecdh_param);
132 cli_ses.ecdh_param = NULL;
133 }
134 #endif
135
136 cli_ses.param_kex_algo = NULL;
137 if (buf_verify(ses.payload, hostkey, ses.hash) != DROPBEAR_SUCCESS) {
114 dropbear_exit("Bad hostkey signature"); 138 dropbear_exit("Bad hostkey signature");
115 } 139 }
116 140
117 sign_key_free(hostkey); 141 sign_key_free(hostkey);
118 hostkey = NULL; 142 hostkey = NULL;