summaryrefslogtreecommitdiffstats
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 ce0bf880..7c4dd7a9 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */
+/* $OpenBSD: kex.c,v 1.100 2015/01/19 19:52:16 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -239,8 +239,8 @@ kex_finish(Kex *kex)
debug("SSH2_MSG_NEWKEYS received");
kex->done = 1;
- buffer_clear(&kex->peer);
- /* buffer_clear(&kex->my); */
+ buffer_clear(kex->peer);
+ /* buffer_clear(kex->my); */
kex->flags &= ~KEX_INIT_SENT;
free(kex->name);
kex->name = NULL;
@@ -264,9 +264,9 @@ kex_send_kexinit(Kex *kex)
kex->done = 0;
/* generate a random cookie */
- if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
+ if (buffer_len(kex->my) < KEX_COOKIE_LEN)
fatal("kex_send_kexinit: kex proposal too short");
- cookie = buffer_ptr(&kex->my);
+ cookie = buffer_ptr(kex->my);
for (i = 0; i < KEX_COOKIE_LEN; i++) {
if (i % 4 == 0)
rnd = arc4random();
@@ -274,7 +274,7 @@ kex_send_kexinit(Kex *kex)
rnd >>= 8;
}
packet_start(SSH2_MSG_KEXINIT);
- packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
+ packet_put_raw(buffer_ptr(kex->my), buffer_len(kex->my));
packet_send();
debug("SSH2_MSG_KEXINIT sent");
kex->flags |= KEX_INIT_SENT;
@@ -284,8 +284,9 @@ kex_send_kexinit(Kex *kex)
void
kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
{
- char *ptr;
- u_int i, dlen;
+ const char *ptr;
+ u_int i;
+ size_t dlen;
Kex *kex = (Kex *)ctxt;
debug("SSH2_MSG_KEXINIT received");
@@ -293,7 +294,7 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
fatal("kex_input_kexinit: no kex, cannot rekey");
ptr = packet_get_raw(&dlen);
- buffer_append(&kex->peer, ptr, dlen);
+ buffer_append(kex->peer, ptr, dlen);
/* discard packet */
for (i = 0; i < KEX_COOKIE_LEN; i++)
@@ -317,15 +318,49 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
kex_kexinit_finish(kex);
}
+void
+kex_free_newkeys(struct newkeys *newkeys)
+{
+ if (newkeys == NULL)
+ return;
+ if (newkeys->enc.key) {
+ explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
+ free(newkeys->enc.key);
+ newkeys->enc.key = NULL;
+ }
+ if (newkeys->enc.iv) {
+ explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
+ free(newkeys->enc.iv);
+ newkeys->enc.iv = NULL;
+ }
+ free(newkeys->enc.name);
+ explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
+ free(newkeys->comp.name);
+ explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
+ mac_clear(&newkeys->mac);
+ if (newkeys->mac.key) {
+ explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
+ free(newkeys->mac.key);
+ newkeys->mac.key = NULL;
+ }
+ free(newkeys->mac.name);
+ explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
+ explicit_bzero(newkeys, sizeof(*newkeys));
+ free(newkeys);
+}
+
Kex *
kex_setup(char *proposal[PROPOSAL_MAX])
{
- Kex *kex;
+ struct kex *kex;
- kex = xcalloc(1, sizeof(*kex));
- buffer_init(&kex->peer);
- buffer_init(&kex->my);
- kex_prop2buf(&kex->my, proposal);
+ if ((kex = calloc(1, sizeof(*kex))) == NULL)
+ fatal("%s: calloc", __func__);
+ if ((kex->peer = sshbuf_new()) == NULL ||
+ (kex->my = sshbuf_new()) == NULL) {
+ fatal("%s: sshbuf_new", __func__);
+ }
+ kex_prop2buf(kex->my, proposal);
kex->done = 0;
kex_send_kexinit(kex); /* we start */
@@ -464,8 +499,8 @@ kex_choose_conf(Kex *kex)
u_int mode, ctos, need, dh_need, authlen;
int first_kex_follows, type;
- my = kex_buf2prop(&kex->my, NULL);
- peer = kex_buf2prop(&kex->peer, &first_kex_follows);
+ my = kex_buf2prop(kex->my, NULL);
+ peer = kex_buf2prop(kex->peer, &first_kex_follows);
if (kex->server) {
cprop=peer;
@@ -591,8 +626,6 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
return digest;
}
-Newkeys *current_keys[MODE_MAX];
-
#define NKEYS 6
void
kex_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,
debug2("kex_derive_keys");
for (mode = 0; mode < MODE_MAX; mode++) {
- current_keys[mode] = kex->newkeys[mode];
- kex->newkeys[mode] = NULL;
ctos = (!kex->server && mode == MODE_OUT) ||
(kex->server && mode == MODE_IN);
- current_keys[mode]->enc.iv = keys[ctos ? 0 : 1];
- current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
- current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
+ kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];
+ kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
+ kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
}
}
@@ -632,16 +663,6 @@ kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret)
}
#endif
-Newkeys *
-kex_get_newkeys(int mode)
-{
- Newkeys *ret;
-
- ret = current_keys[mode];
- current_keys[mode] = NULL;
- return ret;
-}
-
#ifdef WITH_SSH1
void
derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,