summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2015-01-19 19:52:16 +0000
committerDamien Miller <djm@mindrot.org>2015-01-20 09:13:01 +1100
commit091c302829210c41e7f57c3f094c7b9c054306f0 (patch)
tree800de5dc85b877a85d1f269ae5bb09b0dc3fa7a7 /kex.c
parent4e62cc68ce4ba20245d208b252e74e91d3785b74 (diff)
upstream commit
update packet.c & isolate, introduce struct ssh a) switch packet.c to buffer api and isolate per-connection info into struct ssh b) (de)serialization of the state is moved from monitor to packet.c c) the old packet.c API is implemented in opacket.[ch] d) compress.c/h is removed and integrated into packet.c with and ok djm@
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/kex.c b/kex.c
index ce0bf8809..7c4dd7a90 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: kex.c,v 1.100 2015/01/19 19:52:16 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -239,8 +239,8 @@ kex_finish(Kex *kex)
239 debug("SSH2_MSG_NEWKEYS received"); 239 debug("SSH2_MSG_NEWKEYS received");
240 240
241 kex->done = 1; 241 kex->done = 1;
242 buffer_clear(&kex->peer); 242 buffer_clear(kex->peer);
243 /* buffer_clear(&kex->my); */ 243 /* buffer_clear(kex->my); */
244 kex->flags &= ~KEX_INIT_SENT; 244 kex->flags &= ~KEX_INIT_SENT;
245 free(kex->name); 245 free(kex->name);
246 kex->name = NULL; 246 kex->name = NULL;
@@ -264,9 +264,9 @@ kex_send_kexinit(Kex *kex)
264 kex->done = 0; 264 kex->done = 0;
265 265
266 /* generate a random cookie */ 266 /* generate a random cookie */
267 if (buffer_len(&kex->my) < KEX_COOKIE_LEN) 267 if (buffer_len(kex->my) < KEX_COOKIE_LEN)
268 fatal("kex_send_kexinit: kex proposal too short"); 268 fatal("kex_send_kexinit: kex proposal too short");
269 cookie = buffer_ptr(&kex->my); 269 cookie = buffer_ptr(kex->my);
270 for (i = 0; i < KEX_COOKIE_LEN; i++) { 270 for (i = 0; i < KEX_COOKIE_LEN; i++) {
271 if (i % 4 == 0) 271 if (i % 4 == 0)
272 rnd = arc4random(); 272 rnd = arc4random();
@@ -274,7 +274,7 @@ kex_send_kexinit(Kex *kex)
274 rnd >>= 8; 274 rnd >>= 8;
275 } 275 }
276 packet_start(SSH2_MSG_KEXINIT); 276 packet_start(SSH2_MSG_KEXINIT);
277 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); 277 packet_put_raw(buffer_ptr(kex->my), buffer_len(kex->my));
278 packet_send(); 278 packet_send();
279 debug("SSH2_MSG_KEXINIT sent"); 279 debug("SSH2_MSG_KEXINIT sent");
280 kex->flags |= KEX_INIT_SENT; 280 kex->flags |= KEX_INIT_SENT;
@@ -284,8 +284,9 @@ kex_send_kexinit(Kex *kex)
284void 284void
285kex_input_kexinit(int type, u_int32_t seq, void *ctxt) 285kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
286{ 286{
287 char *ptr; 287 const char *ptr;
288 u_int i, dlen; 288 u_int i;
289 size_t dlen;
289 Kex *kex = (Kex *)ctxt; 290 Kex *kex = (Kex *)ctxt;
290 291
291 debug("SSH2_MSG_KEXINIT received"); 292 debug("SSH2_MSG_KEXINIT received");
@@ -293,7 +294,7 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
293 fatal("kex_input_kexinit: no kex, cannot rekey"); 294 fatal("kex_input_kexinit: no kex, cannot rekey");
294 295
295 ptr = packet_get_raw(&dlen); 296 ptr = packet_get_raw(&dlen);
296 buffer_append(&kex->peer, ptr, dlen); 297 buffer_append(kex->peer, ptr, dlen);
297 298
298 /* discard packet */ 299 /* discard packet */
299 for (i = 0; i < KEX_COOKIE_LEN; i++) 300 for (i = 0; i < KEX_COOKIE_LEN; i++)
@@ -317,15 +318,49 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
317 kex_kexinit_finish(kex); 318 kex_kexinit_finish(kex);
318} 319}
319 320
321void
322kex_free_newkeys(struct newkeys *newkeys)
323{
324 if (newkeys == NULL)
325 return;
326 if (newkeys->enc.key) {
327 explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
328 free(newkeys->enc.key);
329 newkeys->enc.key = NULL;
330 }
331 if (newkeys->enc.iv) {
332 explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
333 free(newkeys->enc.iv);
334 newkeys->enc.iv = NULL;
335 }
336 free(newkeys->enc.name);
337 explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
338 free(newkeys->comp.name);
339 explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
340 mac_clear(&newkeys->mac);
341 if (newkeys->mac.key) {
342 explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
343 free(newkeys->mac.key);
344 newkeys->mac.key = NULL;
345 }
346 free(newkeys->mac.name);
347 explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
348 explicit_bzero(newkeys, sizeof(*newkeys));
349 free(newkeys);
350}
351
320Kex * 352Kex *
321kex_setup(char *proposal[PROPOSAL_MAX]) 353kex_setup(char *proposal[PROPOSAL_MAX])
322{ 354{
323 Kex *kex; 355 struct kex *kex;
324 356
325 kex = xcalloc(1, sizeof(*kex)); 357 if ((kex = calloc(1, sizeof(*kex))) == NULL)
326 buffer_init(&kex->peer); 358 fatal("%s: calloc", __func__);
327 buffer_init(&kex->my); 359 if ((kex->peer = sshbuf_new()) == NULL ||
328 kex_prop2buf(&kex->my, proposal); 360 (kex->my = sshbuf_new()) == NULL) {
361 fatal("%s: sshbuf_new", __func__);
362 }
363 kex_prop2buf(kex->my, proposal);
329 kex->done = 0; 364 kex->done = 0;
330 365
331 kex_send_kexinit(kex); /* we start */ 366 kex_send_kexinit(kex); /* we start */
@@ -464,8 +499,8 @@ kex_choose_conf(Kex *kex)
464 u_int mode, ctos, need, dh_need, authlen; 499 u_int mode, ctos, need, dh_need, authlen;
465 int first_kex_follows, type; 500 int first_kex_follows, type;
466 501
467 my = kex_buf2prop(&kex->my, NULL); 502 my = kex_buf2prop(kex->my, NULL);
468 peer = kex_buf2prop(&kex->peer, &first_kex_follows); 503 peer = kex_buf2prop(kex->peer, &first_kex_follows);
469 504
470 if (kex->server) { 505 if (kex->server) {
471 cprop=peer; 506 cprop=peer;
@@ -591,8 +626,6 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
591 return digest; 626 return digest;
592} 627}
593 628
594Newkeys *current_keys[MODE_MAX];
595
596#define NKEYS 6 629#define NKEYS 6
597void 630void
598kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, 631kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen,
@@ -608,13 +641,11 @@ kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen,
608 641
609 debug2("kex_derive_keys"); 642 debug2("kex_derive_keys");
610 for (mode = 0; mode < MODE_MAX; mode++) { 643 for (mode = 0; mode < MODE_MAX; mode++) {
611 current_keys[mode] = kex->newkeys[mode];
612 kex->newkeys[mode] = NULL;
613 ctos = (!kex->server && mode == MODE_OUT) || 644 ctos = (!kex->server && mode == MODE_OUT) ||
614 (kex->server && mode == MODE_IN); 645 (kex->server && mode == MODE_IN);
615 current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; 646 kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];
616 current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; 647 kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
617 current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; 648 kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
618 } 649 }
619} 650}
620 651
@@ -632,16 +663,6 @@ kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret)
632} 663}
633#endif 664#endif
634 665
635Newkeys *
636kex_get_newkeys(int mode)
637{
638 Newkeys *ret;
639
640 ret = current_keys[mode];
641 current_keys[mode] = NULL;
642 return ret;
643}
644
645#ifdef WITH_SSH1 666#ifdef WITH_SSH1
646void 667void
647derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, 668derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,