summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/kex.c b/kex.c
index a0a5b46fe..3b42d3240 100644
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kex.c,v 1.26 2001/04/03 19:53:29 markus Exp $"); 26RCSID("$OpenBSD: kex.c,v 1.27 2001/04/03 23:32:11 markus Exp $");
27 27
28#include <openssl/crypto.h> 28#include <openssl/crypto.h>
29 29
@@ -131,7 +131,7 @@ kex_input_newkeys(int type, int plen, void *ctxt)
131 for (i = 30; i <= 49; i++) 131 for (i = 30; i <= 49; i++)
132 dispatch_set(i, &kex_protocol_error); 132 dispatch_set(i, &kex_protocol_error);
133 buffer_clear(&kex->peer); 133 buffer_clear(&kex->peer);
134 buffer_clear(&kex->my); 134 /* buffer_clear(&kex->my); */
135 kex->flags &= ~KEX_INIT_SENT; 135 kex->flags &= ~KEX_INIT_SENT;
136} 136}
137 137
@@ -152,7 +152,6 @@ kex_input_kexinit(int type, int plen, void *ctxt)
152 int dlen; 152 int dlen;
153 Kex *kex = (Kex *)ctxt; 153 Kex *kex = (Kex *)ctxt;
154 154
155 dispatch_set(SSH2_MSG_KEXINIT, &kex_protocol_error);
156 debug("SSH2_MSG_KEXINIT received"); 155 debug("SSH2_MSG_KEXINIT received");
157 156
158 ptr = packet_get_raw(&dlen); 157 ptr = packet_get_raw(&dlen);
@@ -274,18 +273,20 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
274} 273}
275 274
276void 275void
277kex_choose_conf(Kex *k) 276kex_choose_conf(Kex *kex)
278{ 277{
278 Newkeys *newkeys;
279 char **my, **peer; 279 char **my, **peer;
280 char **cprop, **sprop; 280 char **cprop, **sprop;
281 int nenc, nmac, ncomp;
281 int mode; 282 int mode;
282 int ctos; /* direction: if true client-to-server */ 283 int ctos; /* direction: if true client-to-server */
283 int need; 284 int need;
284 285
285 my = kex_buf2prop(&k->my); 286 my = kex_buf2prop(&kex->my);
286 peer = kex_buf2prop(&k->peer); 287 peer = kex_buf2prop(&kex->peer);
287 288
288 if (k->server) { 289 if (kex->server) {
289 cprop=peer; 290 cprop=peer;
290 sprop=my; 291 sprop=my;
291 } else { 292 } else {
@@ -294,42 +295,44 @@ kex_choose_conf(Kex *k)
294 } 295 }
295 296
296 for (mode = 0; mode < MODE_MAX; mode++) { 297 for (mode = 0; mode < MODE_MAX; mode++) {
297 int nenc, nmac, ncomp; 298 newkeys = xmalloc(sizeof(*newkeys));
298 ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); 299 memset(newkeys, 0, sizeof(*newkeys));
300 kex->keys[mode] = newkeys;
301 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
299 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; 302 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
300 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; 303 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
301 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; 304 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
302 choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]); 305 choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]);
303 choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); 306 choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]);
304 choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); 307 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
305 debug("kex: %s %s %s %s", 308 debug("kex: %s %s %s %s",
306 ctos ? "client->server" : "server->client", 309 ctos ? "client->server" : "server->client",
307 k->enc[mode].name, 310 newkeys->enc.name,
308 k->mac[mode].name, 311 newkeys->mac.name,
309 k->comp[mode].name); 312 newkeys->comp.name);
310 } 313 }
311 choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); 314 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
312 choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 315 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
313 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); 316 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
314 need = 0; 317 need = 0;
315 for (mode = 0; mode < MODE_MAX; mode++) { 318 for (mode = 0; mode < MODE_MAX; mode++) {
316 if (need < k->enc[mode].cipher->key_len) 319 newkeys = kex->keys[mode];
317 need = k->enc[mode].cipher->key_len; 320 if (need < newkeys->enc.cipher->key_len)
318 if (need < k->enc[mode].cipher->block_size) 321 need = newkeys->enc.cipher->key_len;
319 need = k->enc[mode].cipher->block_size; 322 if (need < newkeys->enc.cipher->block_size)
320 if (need < k->mac[mode].key_len) 323 need = newkeys->enc.cipher->block_size;
321 need = k->mac[mode].key_len; 324 if (need < newkeys->mac.key_len)
325 need = newkeys->mac.key_len;
322 } 326 }
323 /* XXX need runden? */ 327 /* XXX need runden? */
324 k->we_need = need; 328 kex->we_need = need;
325 329
326 kex_prop_free(my); 330 kex_prop_free(my);
327 kex_prop_free(peer); 331 kex_prop_free(peer);
328
329} 332}
330 333
331u_char * 334u_char *
332derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret) 335derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
333{ 336{
334 Buffer b; 337 Buffer b;
335 EVP_MD *evp_md = EVP_sha1(); 338 EVP_MD *evp_md = EVP_sha1();
@@ -346,7 +349,7 @@ derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret)
346 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */ 349 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */
347 EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */ 350 EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */
348 EVP_DigestUpdate(&md, &c, 1); /* key id */ 351 EVP_DigestUpdate(&md, &c, 1); /* key id */
349 EVP_DigestUpdate(&md, hash, mdsz); /* session id */ 352 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
350 EVP_DigestFinal(&md, digest, NULL); 353 EVP_DigestFinal(&md, digest, NULL);
351 354
352 /* expand */ 355 /* expand */
@@ -365,26 +368,36 @@ derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret)
365 return digest; 368 return digest;
366} 369}
367 370
371Newkeys *x_newkeys[MODE_MAX];
372
368#define NKEYS 6 373#define NKEYS 6
369void 374void
370kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret) 375kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
371{ 376{
372 int i; 377 Newkeys *newkeys;
373 int mode;
374 int ctos;
375 u_char *keys[NKEYS]; 378 u_char *keys[NKEYS];
379 int i, mode, ctos;
376 380
377 for (i = 0; i < NKEYS; i++) 381 for (i = 0; i < NKEYS; i++)
378 keys[i] = derive_key('A'+i, k->we_need, hash, shared_secret); 382 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);
379 383
384 debug("kex_derive_keys");
380 for (mode = 0; mode < MODE_MAX; mode++) { 385 for (mode = 0; mode < MODE_MAX; mode++) {
381 ctos = (!k->server && mode == MODE_OUT) || (k->server && mode == MODE_IN); 386 newkeys = kex->keys[mode];
382 k->enc[mode].iv = keys[ctos ? 0 : 1]; 387 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
383 k->enc[mode].key = keys[ctos ? 2 : 3]; 388 newkeys->enc.iv = keys[ctos ? 0 : 1];
384 k->mac[mode].key = keys[ctos ? 4 : 5]; 389 newkeys->enc.key = keys[ctos ? 2 : 3];
390 newkeys->mac.key = keys[ctos ? 4 : 5];
391 x_newkeys[mode] = newkeys;
385 } 392 }
386} 393}
387 394
395Newkeys *
396kex_get_newkeys(int mode)
397{
398 return x_newkeys[mode];
399}
400
388#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) 401#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
389void 402void
390dump_digest(char *msg, u_char *digest, int len) 403dump_digest(char *msg, u_char *digest, int len)