Mercurial > dropbear
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; |