[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [gnunet] branch master updated: complete new KX implementat
From: |
gnunet |
Subject: |
[GNUnet-SVN] [gnunet] branch master updated: complete new KX implementation, including KX_AUTH defense against KX-injection based reset attacks |
Date: |
Sat, 28 Jan 2017 22:52:06 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new d50ef7d2d complete new KX implementation, including KX_AUTH defense
against KX-injection based reset attacks
d50ef7d2d is described below
commit d50ef7d2d9631f56be7ad0d74d21fd78ed9d4cc2
Author: Christian Grothoff <address@hidden>
AuthorDate: Sat Jan 28 22:51:58 2017 +0100
complete new KX implementation, including KX_AUTH defense against
KX-injection based reset attacks
---
src/cadet/gnunet-service-cadet-new_connection.c | 33 +-
src/cadet/gnunet-service-cadet-new_connection.h | 11 +
src/cadet/gnunet-service-cadet-new_core.c | 45 ++
src/cadet/gnunet-service-cadet-new_tunnels.c | 571 ++++++++++++++++++------
src/cadet/gnunet-service-cadet-new_tunnels.h | 34 +-
src/cadet/gnunet-service-cadet_tunnel.c | 18 +-
src/cadet/gnunet-service-cadet_tunnel.h | 4 +-
src/cadet/test_cadet.c | 3 +-
8 files changed, 575 insertions(+), 144 deletions(-)
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c
b/src/cadet/gnunet-service-cadet-new_connection.c
index a098674f5..11044d9e6 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ b/src/cadet/gnunet-service-cadet-new_connection.c
@@ -1,4 +1,3 @@
-
/*
This file is part of GNUnet.
Copyright (C) 2001-2017 GNUnet e.V.
@@ -302,6 +301,14 @@ send_keepalive (void *cls)
struct GNUNET_MessageHeader msg;
cc->task = NULL;
+ if (CADET_TUNNEL_KEY_OK != GCT_get_estate (cc->ct->t))
+ {
+ /* Tunnel not yet ready, wait with keepalives... */
+ cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
+ &send_keepalive,
+ cc);
+ return;
+ }
GNUNET_assert (NULL != cc->ct);
GNUNET_assert (GNUNET_YES == cc->mqm_ready);
GNUNET_assert (NULL == cc->keepalive_qe);
@@ -383,6 +390,30 @@ GCC_handle_kx (struct CadetConnection *cc,
/**
+ * Handle KX_AUTH message.
+ *
+ * @param cc connection that received encrypted message
+ * @param msg the key exchange message
+ */
+void
+GCC_handle_kx_auth (struct CadetConnection *cc,
+ const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
*msg)
+{
+ if (CADET_CONNECTION_SENT == cc->state)
+ {
+ /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload.
That's fine,
+ clearly something is working, so pretend we got an ACK. */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
+ GCC_2s (cc));
+ GCC_handle_connection_create_ack (cc);
+ }
+ GCT_handle_kx_auth (cc->ct,
+ msg);
+}
+
+
+/**
* Handle encrypted message.
*
* @param cc connection that received encrypted message
diff --git a/src/cadet/gnunet-service-cadet-new_connection.h
b/src/cadet/gnunet-service-cadet-new_connection.h
index 692d03e4c..cea1e8024 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.h
+++ b/src/cadet/gnunet-service-cadet-new_connection.h
@@ -159,6 +159,17 @@ GCC_handle_kx (struct CadetConnection *cc,
/**
+ * Handle KX_AUTH message.
+ *
+ * @param cc connection that received encrypted message
+ * @param msg the key exchange message
+ */
+void
+GCC_handle_kx_auth (struct CadetConnection *cc,
+ const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
*msg);
+
+
+/**
* Handle encrypted message.
*
* @param cc connection that received encrypted message
diff --git a/src/cadet/gnunet-service-cadet-new_core.c
b/src/cadet/gnunet-service-cadet-new_core.c
index b4b1e6305..956a1207d 100644
--- a/src/cadet/gnunet-service-cadet-new_core.c
+++ b/src/cadet/gnunet-service-cadet-new_core.c
@@ -744,6 +744,47 @@ handle_tunnel_kx (void *cls,
/**
+ * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
+ *
+ * @param cls Closure (CadetPeer for neighbor that sent the message).
+ * @param msg Message itself.
+ */
+static void
+handle_tunnel_kx_auth (void *cls,
+ const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
*msg)
+{
+ struct CadetPeer *peer = cls;
+ struct CadetConnection *cc;
+
+ /* First, check if message belongs to a connection that ends here. */
+ cc = GNUNET_CONTAINER_multishortmap_get (connections,
+ &msg->kx.cid.connection_of_tunnel);
+ if (NULL != cc)
+ {
+ /* verify message came from the right direction */
+ struct CadetPeerPath *path = GCC_get_path (cc);
+
+ if (peer !=
+ GCPP_get_peer_at_offset (path,
+ 0))
+ {
+ /* received message from unexpected direction, ignore! */
+ GNUNET_break_op (0);
+ return;
+ }
+ GCC_handle_kx_auth (cc,
+ msg);
+ return;
+ }
+
+ /* We're just an intermediary peer, route the message along its path */
+ route_message (peer,
+ &msg->kx.cid,
+ &msg->kx.header);
+}
+
+
+/**
* Check if the encrypted message has the appropriate size.
*
* @param cls Closure (unused).
@@ -901,6 +942,10 @@ GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
struct GNUNET_CADET_TunnelKeyExchangeMessage,
NULL),
+ GNUNET_MQ_hd_fixed_size (tunnel_kx_auth,
+ GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH,
+ struct GNUNET_CADET_TunnelKeyExchangeAuthMessage,
+ NULL),
GNUNET_MQ_hd_var_size (tunnel_encrypted,
GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
struct GNUNET_CADET_TunnelEncryptedMessage,
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c
b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 4d4cdc2dc..f98f46b9b 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -24,10 +24,6 @@
* @author Christian Grothoff
*
* FIXME:
- * - KX:
- * + clean up KX logic, including adding sender authentication
- * + implement rekeying
- * + check KX estate machine -- make sure it is never stuck!
* - connection management
* + properly (evaluate, kill old ones, search for new ones)
* + when managing connections, distinguish those that
@@ -62,6 +58,12 @@
#define IDLE_DESTROY_DELAY
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90)
/**
+ * How long do we wait initially before retransmitting the KX?
+ * TODO: replace by 2 RTT if/once we have connection-level RTT data!
+ */
+#define INITIAL_KX_RETRY_DELAY
GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
+
+/**
* Maximum number of skipped keys we keep in memory per tunnel.
*/
#define MAX_SKIPPED_KEYS 64
@@ -171,12 +173,16 @@ struct CadetTunnelAxolotl
struct GNUNET_CRYPTO_SymmetricSessionKey CKr;
/**
- * ECDH for key exchange (A0 / B0).
+ * ECDH for key exchange (A0 / B0). Note that for the
+ * 'unverified_ax', this member is an alias with the main
+ * 't->ax.kx_0' value, so do not free it!
*/
struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0;
/**
- * ECDH Ratchet key (our private key in the current DH).
+ * ECDH Ratchet key (our private key in the current DH). Note that
+ * for the 'unverified_ax', this member is an alias with the main
+ * 't->ax.kx_0' value, so do not free it!
*/
struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs;
@@ -421,6 +427,11 @@ struct CadetTunnel
*/
enum CadetTunnelEState estate;
+ /**
+ * Force triggering KX_AUTH independent of @e estate.
+ */
+ int kx_auth_requested;
+
};
@@ -460,17 +471,24 @@ estate2s (enum CadetTunnelEState es)
switch (es)
{
- case CADET_TUNNEL_KEY_UNINITIALIZED:
- return "CADET_TUNNEL_KEY_UNINITIALIZED";
- case CADET_TUNNEL_KEY_SENT:
- return "CADET_TUNNEL_KEY_SENT";
- case CADET_TUNNEL_KEY_PING:
- return "CADET_TUNNEL_KEY_PING";
- case CADET_TUNNEL_KEY_OK:
- return "CADET_TUNNEL_KEY_OK";
- default:
- SPRINTF (buf, "%u (UNKNOWN STATE)", es);
- return buf;
+ case CADET_TUNNEL_KEY_UNINITIALIZED:
+ return "CADET_TUNNEL_KEY_UNINITIALIZED";
+ case CADET_TUNNEL_KEY_AX_RECV:
+ return "CADET_TUNNEL_KEY_AX_RECV";
+ case CADET_TUNNEL_KEY_AX_SENT:
+ return "CADET_TUNNEL_KEY_AX_SENT";
+ case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
+ return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT:
+ return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
+ case CADET_TUNNEL_KEY_OK:
+ return "CADET_TUNNEL_KEY_OK";
+ default:
+ GNUNET_snprintf (buf,
+ sizeof (buf),
+ "%u (UNKNOWN STATE)",
+ es);
+ return buf;
}
}
@@ -602,6 +620,8 @@ static void
new_ephemeral (struct CadetTunnelAxolotl *ax)
{
GNUNET_free_non_null (ax->DHRs);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating new ephemeral ratchet key (DHRs)\n");
ax->DHRs = GNUNET_CRYPTO_ecdhe_key_create ();
}
@@ -1227,10 +1247,10 @@ GCT_change_estate (struct CadetTunnel *t,
t->estate = state;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s estate changed from %d to %d\n",
+ "%s estate changed from %s to %s\n",
GCT_2s (t),
- old,
- state);
+ estate2s (old),
+ estate2s (state));
if ( (CADET_TUNNEL_KEY_OK != old) &&
(CADET_TUNNEL_KEY_OK == t->estate) )
@@ -1244,6 +1264,10 @@ GCT_change_estate (struct CadetTunnel *t,
GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
¬ify_tunnel_up_cb,
t);
+ if (NULL != t->send_task)
+ GNUNET_SCHEDULER_cancel (t->send_task);
+ t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
+ t);
}
}
@@ -1251,16 +1275,12 @@ GCT_change_estate (struct CadetTunnel *t,
/**
* Send a KX message.
*
- * FIXME: does not take care of sender-authentication yet!
- *
* @param t Tunnel on which to send it.
* @param ax axolotl key context to use
- * @param force_reply Force the other peer to reply with a KX message.
*/
static void
send_kx (struct CadetTunnel *t,
- struct CadetTunnelAxolotl *ax,
- int force_reply)
+ struct CadetTunnelAxolotl *ax)
{
struct CadetTConnection *ct;
struct CadetConnection *cc;
@@ -1272,22 +1292,21 @@ send_kx (struct CadetTunnel *t,
if (NULL == ct)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Wanted to send KX on tunnel %s, but no connection is ready,
deferring\n",
+ "Wanted to send KX on %s, but no connection is ready, deferring\n",
GCT_2s (t));
+ t->next_kx_attempt = GNUNET_TIME_absolute_get ();
return;
}
cc = ct->cc;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Sending KX on tunnel %s using connection %s\n",
+ "Sending KX on %s using %s in state %s\n",
GCT_2s (t),
- GCC_2s (ct->cc));
+ GCC_2s (ct->cc),
+ estate2s (t->estate));
- // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t));
env = GNUNET_MQ_msg (msg,
GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX);
- flags = GNUNET_CADET_KX_FLAG_NONE;
- if (GNUNET_YES == force_reply)
- flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY;
+ flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
msg->flags = htonl (flags);
msg->cid = *GCC_get_id (cc);
GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0,
@@ -1295,13 +1314,88 @@ send_kx (struct CadetTunnel *t,
GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs,
&msg->ratchet_key);
ct->is_ready = GNUNET_NO;
- GCC_transmit (cc,
- env);
t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
GCT_change_estate (t,
- CADET_TUNNEL_KEY_SENT);
+ CADET_TUNNEL_KEY_AX_SENT);
+ else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
+ GCT_change_estate (t,
+ CADET_TUNNEL_KEY_AX_SENT_AND_RECV);
+ GCC_transmit (cc,
+ env);
+}
+
+
+/**
+ * Send a KX_AUTH message.
+ *
+ * @param t Tunnel on which to send it.
+ * @param ax axolotl key context to use
+ * @param force_reply Force the other peer to reply with a KX_AUTH message
+ * (set if we would like to transmit right now, but cannot)
+ */
+static void
+send_kx_auth (struct CadetTunnel *t,
+ struct CadetTunnelAxolotl *ax,
+ int force_reply)
+{
+ struct CadetTConnection *ct;
+ struct CadetConnection *cc;
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg;
+ enum GNUNET_CADET_KX_Flags flags;
+
+ ct = get_ready_connection (t);
+ if (NULL == ct)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Wanted to send KX_AUTH on %s, but no connection is ready,
deferring\n",
+ GCT_2s (t));
+ t->next_kx_attempt = GNUNET_TIME_absolute_get ();
+ t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate
*/
+ return;
+ }
+ t->kx_auth_requested = GNUNET_NO; /* clear flag */
+ cc = ct->cc;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending KX_AUTH on %s using %s\n",
+ GCT_2s (t),
+ GCC_2s (ct->cc));
+
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH);
+ flags = GNUNET_CADET_KX_FLAG_NONE;
+ if (GNUNET_YES == force_reply)
+ flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY;
+ msg->kx.flags = htonl (flags);
+ msg->kx.cid = *GCC_get_id (cc);
+ GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0,
+ &msg->kx.ephemeral_key);
+ GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs,
+ &msg->kx.ratchet_key);
+ /* Compute authenticator (this is the main difference to #send_kx()) */
+ GNUNET_CRYPTO_hash (&ax->RK,
+ sizeof (ax->RK),
+ &msg->auth);
+
+ /* Compute when to be triggered again; actual job will
+ be scheduled via #connection_ready_cb() */
+ t->kx_retry_delay
+ = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
+ t->next_kx_attempt
+ = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
+
+ /* Send via cc, mark it as unready */
+ ct->is_ready = GNUNET_NO;
+
+ /* Update state machine, unless we are already OK */
+ if (CADET_TUNNEL_KEY_OK != t->estate)
+ GCT_change_estate (t,
+ CADET_TUNNEL_KEY_AX_AUTH_SENT);
+
+ GCC_transmit (cc,
+ env);
}
@@ -1446,6 +1540,91 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
/**
+ * Try to redo the KX or KX_AUTH handshake, if we can.
+ *
+ * @param cls the `struct CadetTunnel` to do KX for.
+ */
+static void
+retry_kx (void *cls)
+{
+ struct CadetTunnel *t = cls;
+ struct CadetTunnelAxolotl *ax;
+
+ t->kx_task = NULL;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to make KX progress on %s in state %s\n",
+ GCT_2s (t),
+ estate2s (t->estate));
+ switch (t->estate)
+ {
+ case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
+ case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
+ send_kx (t,
+ &t->ax);
+ break;
+ case CADET_TUNNEL_KEY_AX_RECV:
+ case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
+ /* We are responding, so only require reply
+ if WE have a channel waiting. */
+ if (NULL != t->unverified_ax)
+ {
+ /* Send AX_AUTH so we might get this one verified */
+ ax = t->unverified_ax;
+ }
+ else
+ {
+ /* How can this be? */
+ GNUNET_break (0);
+ ax = &t->ax;
+ }
+ send_kx_auth (t,
+ ax,
+ (0 == GCT_count_channels (t))
+ ? GNUNET_NO
+ : GNUNET_YES);
+ break;
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT:
+ /* We are responding, so only require reply
+ if WE have a channel waiting. */
+ if (NULL != t->unverified_ax)
+ {
+ /* Send AX_AUTH so we might get this one verified */
+ ax = t->unverified_ax;
+ }
+ else
+ {
+ /* How can this be? */
+ GNUNET_break (0);
+ ax = &t->ax;
+ }
+ send_kx_auth (t,
+ ax,
+ (0 == GCT_count_channels (t))
+ ? GNUNET_NO
+ : GNUNET_YES);
+ break;
+ case CADET_TUNNEL_KEY_OK:
+ /* Must have been the *other* peer asking us to
+ respond with a KX_AUTH. */
+ if (NULL != t->unverified_ax)
+ {
+ /* Sending AX_AUTH in response to AX so we might get this one verified */
+ ax = t->unverified_ax;
+ }
+ else
+ {
+ /* Sending AX_AUTH in response to AX_AUTH */
+ ax = &t->ax;
+ }
+ send_kx_auth (t,
+ ax,
+ GNUNET_NO);
+ break;
+ }
+}
+
+
+/**
* Handle KX message that lacks authentication (and which will thus
* only be considered authenticated after we respond with our own
* KX_AUTH and finally successfully decrypt payload).
@@ -1461,50 +1640,62 @@ GCT_handle_kx (struct CadetTConnection *ct,
struct CadetTunnelAxolotl *ax;
int ret;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Handling KX message for tunnel %s\n",
- GCT_2s (t));
+ if (0 ==
+ memcmp (&t->ax.DHRr,
+ &msg->ratchet_key,
+ sizeof (msg->ratchet_key)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got duplicate KX. Firing back KX_AUTH.\n");
+ send_kx_auth (t,
+ &t->ax,
+ GNUNET_NO);
+ return;
+ }
/* We only keep ONE unverified KX around, so if there is an existing one,
clean it up. */
if (NULL != t->unverified_ax)
{
+ if (0 ==
+ memcmp (&t->unverified_ax->DHRr,
+ &msg->ratchet_key,
+ sizeof (msg->ratchet_key)))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got duplicate unverified KX on %s. Fire back KX_AUTH again.\n",
+ GCT_2s (t));
+ send_kx_auth (t,
+ t->unverified_ax,
+ GNUNET_NO);
+ return;
+ }
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Dropping old unverified KX state, got a fresh one.\n",
- t->unverified_attempts);
- cleanup_ax (t->unverified_ax);
+ "Dropping old unverified KX state. Got a fresh KX for %s.\n",
+ GCT_2s (t));
memset (t->unverified_ax,
0,
sizeof (struct CadetTunnelAxolotl));
- new_ephemeral (t->unverified_ax);
- t->unverified_ax->kx_0 = GNUNET_CRYPTO_ecdhe_key_create ();
+ t->unverified_ax->DHRs = t->ax.DHRs;
+ t->unverified_ax->kx_0 = t->ax.kx_0;
}
else
{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating fresh unverified KX for %s.\n",
+ GCT_2s (t));
t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
- new_ephemeral (t->unverified_ax);
- t->unverified_ax->kx_0 = GNUNET_CRYPTO_ecdhe_key_create ();
+ t->unverified_ax->DHRs = t->ax.DHRs;
+ t->unverified_ax->kx_0 = t->ax.kx_0;
}
- /* Set as the 'current' RK the one we are currently using,
+ /* Set as the 'current' RK/DHRr the one we are currently using,
so that the duplicate-detection logic of
#update_ax_by_kx can work. */
t->unverified_ax->RK = t->ax.RK;
+ t->unverified_ax->DHRr = t->ax.DHRr;
t->unverified_attempts = 0;
ax = t->unverified_ax;
- /* FIXME: why this? Investigate use of kx_task! */
- if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags)))
- {
- if (NULL != t->kx_task)
- {
- GNUNET_SCHEDULER_cancel (t->kx_task);
- t->kx_task = NULL;
- }
- send_kx (t,
- ax,
- GNUNET_NO);
- }
-
/* Update 'ax' by the new key material */
ret = update_ax_by_kx (ax,
GCP_get_id (t->destination),
@@ -1515,33 +1706,110 @@ GCT_handle_kx (struct CadetTConnection *ct,
return; /* duplicate KX, nothing to do */
/* move ahead in our state machine */
+ if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
+ GCT_change_estate (t,
+ CADET_TUNNEL_KEY_AX_RECV);
+ else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
+ GCT_change_estate (t,
+ CADET_TUNNEL_KEY_AX_SENT_AND_RECV);
+
+ /* KX is still not done, try again our end. */
+ if (CADET_TUNNEL_KEY_OK != t->estate)
+ {
+ if (NULL != t->kx_task)
+ GNUNET_SCHEDULER_cancel (t->kx_task);
+ t->kx_task
+ = GNUNET_SCHEDULER_add_now (&retry_kx,
+ t);
+ }
+}
+
+
+/**
+ * Handle KX_AUTH message.
+ *
+ * @param ct connection/tunnel combo that received encrypted message
+ * @param msg the key exchange message
+ */
+void
+GCT_handle_kx_auth (struct CadetTConnection *ct,
+ const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
*msg)
+{
+ struct CadetTunnel *t = ct->t;
+ struct CadetTunnelAxolotl ax_tmp;
+ struct GNUNET_HashCode kx_auth;
+ int ret;
+
+ if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
+ (CADET_TUNNEL_KEY_AX_RECV == t->estate) )
+ {
+ /* Confusing, we got a KX_AUTH before we even send our own
+ KX. This should not happen. We'll send our own KX ASAP anyway,
+ so let's ignore this here. */
+ GNUNET_break_op (0);
+ return;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Handling KX_AUTH message for %s\n",
+ GCT_2s (t));
+
+ /* We do everything in ax_tmp until we've checked the authentication
+ so we don't clobber anything we care about by accident. */
+ ax_tmp = t->ax;
+
+ /* Update 'ax' by the new key material */
+ ret = update_ax_by_kx (&ax_tmp,
+ GCP_get_id (t->destination),
+ &msg->kx.ephemeral_key,
+ &msg->kx.ratchet_key);
+ GNUNET_break (GNUNET_OK == ret);
+ GNUNET_CRYPTO_hash (&ax_tmp.RK,
+ sizeof (ax_tmp.RK),
+ &kx_auth);
+ if (0 != memcmp (&kx_auth,
+ &msg->auth,
+ sizeof (kx_auth)))
+ {
+ /* This KX_AUTH is not using the latest KX/KX_AUTH data
+ we transmitted to the sender, refuse it! */
+ GNUNET_break_op (0);
+ return;
+ }
+ /* Yep, we're good. */
+ t->ax = ax_tmp;
+ if (NULL != t->unverified_ax)
+ {
+ /* We got some "stale" KX before, drop that. */
+ t->unverified_ax->DHRs = NULL; /* aliased with ax.DHRs */
+ t->unverified_ax->kx_0 = NULL; /* aliased with ax.DHRs */
+ cleanup_ax (t->unverified_ax);
+ GNUNET_free (t->unverified_ax);
+ t->unverified_ax = NULL;
+ }
+
+ /* move ahead in our state machine */
switch (t->estate)
{
case CADET_TUNNEL_KEY_UNINITIALIZED:
- GCT_change_estate (t,
- CADET_TUNNEL_KEY_PING);
+ case CADET_TUNNEL_KEY_AX_RECV:
+ /* Checked above, this is impossible. */
+ GNUNET_assert (0);
break;
- case CADET_TUNNEL_KEY_SENT:
- /* Got a response to us sending our key; now
- we can start transmitting! */
+ case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
+ case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
GCT_change_estate (t,
CADET_TUNNEL_KEY_OK);
- if (NULL != t->send_task)
- GNUNET_SCHEDULER_cancel (t->send_task);
- t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
- t);
- break;
- case CADET_TUNNEL_KEY_PING:
- /* Got a key yet again; need encrypted payload or KX_AUTH
- to advance to #CADET_TUNNEL_KEY_OK! */
break;
case CADET_TUNNEL_KEY_OK:
- /* Did not expect a key, but so what. */
+ /* Did not expect another KX_AUTH, but so what, still acceptable.
+ Nothing to do here. */
break;
}
}
+
/* ************************************** end core crypto
***************************** */
@@ -1603,11 +1871,33 @@ GCT_add_channel (struct CadetTunnel *t,
ch,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding channel %s to tunnel %s\n",
+ "Adding %s to %s\n",
GCCH_2s (ch),
GCT_2s (t));
- if (CADET_TUNNEL_KEY_OK == t->estate)
+ switch (t->estate)
+ {
+ case CADET_TUNNEL_KEY_UNINITIALIZED:
+ /* waiting for connection to start KX */
+ break;
+ case CADET_TUNNEL_KEY_AX_RECV:
+ case CADET_TUNNEL_KEY_AX_SENT:
+ case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
+ /* we're currently waiting for KX to complete */
+ break;
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT:
+ /* waiting for OTHER peer to send us data,
+ we might need to prompt more aggressively! */
+ if (NULL == t->kx_task)
+ t->kx_task
+ = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
+ &retry_kx,
+ t);
+ break;
+ case CADET_TUNNEL_KEY_OK:
+ /* We are ready. Tell the new channel that we are up. */
GCCH_tunnel_up (ch);
+ break;
+ }
return ctn;
}
@@ -1644,9 +1934,9 @@ destroy_tunnel (void *cls)
t->destroy_task = NULL;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Destroying idle tunnel %s\n",
+ "Destroying idle %s\n",
GCT_2s (t));
- GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels));
+ GNUNET_assert (0 == GCT_count_channels (t));
while (NULL != (ct = t->connection_head))
{
struct CadetConnection *cc;
@@ -1682,12 +1972,14 @@ destroy_tunnel (void *cls)
}
GNUNET_MST_destroy (t->mst);
GNUNET_MQ_destroy (t->mq);
- cleanup_ax (&t->ax);
if (NULL != t->unverified_ax)
{
+ t->unverified_ax->DHRs = NULL; /* aliased with ax.DHRs */
+ t->unverified_ax->kx_0 = NULL; /* aliased with ax.DHRs */
cleanup_ax (t->unverified_ax);
GNUNET_free (t->unverified_ax);
}
+ cleanup_ax (&t->ax);
GNUNET_free (t);
}
@@ -1705,7 +1997,7 @@ GCT_remove_channel (struct CadetTunnel *t,
struct GNUNET_CADET_ChannelTunnelNumber ctn)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Removing channel %s from tunnel %s\n",
+ "Removing %s from %s\n",
GCCH_2s (ch),
GCT_2s (t));
GNUNET_assert (GNUNET_YES ==
@@ -1713,7 +2005,7 @@ GCT_remove_channel (struct CadetTunnel *t,
ntohl (ctn.cn),
ch));
if (0 ==
- GNUNET_CONTAINER_multihashmap32_size (t->channels))
+ GCT_count_channels (t))
{
t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY,
&destroy_tunnel,
@@ -1755,7 +2047,7 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t)
&destroy_remaining_channels,
t);
GNUNET_assert (0 ==
- GNUNET_CONTAINER_multihashmap32_size (t->channels));
+ GCT_count_channels (t));
if (NULL != t->destroy_task)
{
GNUNET_SCHEDULER_cancel (t->destroy_task);
@@ -1766,26 +2058,6 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t)
/**
- * It's been a while, we should try to redo the KX, if we can.
- *
- * @param cls the `struct CadetTunnel` to do KX for.
- */
-static void
-retry_kx (void *cls)
-{
- struct CadetTunnel *t = cls;
-
- t->kx_task = NULL;
- send_kx (t,
- &t->ax,
- ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
- (CADET_TUNNEL_KEY_SENT == t->estate) )
- ? GNUNET_YES
- : GNUNET_NO);
-}
-
-
-/**
* Send normal payload from queue in @a t via connection @a ct.
* Does nothing if our payload queue is empty.
*
@@ -1847,7 +2119,7 @@ connection_ready_cb (void *cls,
if (GNUNET_NO == is_ready)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Connection %s no longer ready for tunnel %s\n",
+ "%s no longer ready for %s\n",
GCC_2s (ct->cc),
GCT_2s (t));
ct->is_ready = GNUNET_NO;
@@ -1855,29 +2127,50 @@ connection_ready_cb (void *cls,
}
ct->is_ready = GNUNET_YES;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Connection %s now ready for tunnel %s in state %s\n",
+ "%s now ready for %s in state %s\n",
GCC_2s (ct->cc),
GCT_2s (t),
estate2s (t->estate));
switch (t->estate)
{
case CADET_TUNNEL_KEY_UNINITIALIZED:
+ /* Do not begin KX if WE have no channels waiting! */
+ if (0 == GCT_count_channels (t))
+ return;
+ /* We are uninitialized, just transmit immediately,
+ without undue delay. */
+ if (NULL != t->kx_task)
+ {
+ GNUNET_SCHEDULER_cancel (t->kx_task);
+ t->kx_task = NULL;
+ }
send_kx (t,
- &t->ax,
- GNUNET_YES);
+ &t->ax);
break;
- case CADET_TUNNEL_KEY_SENT:
- case CADET_TUNNEL_KEY_PING:
- /* opportunity to #retry_kx() starts now, schedule job */
+ case CADET_TUNNEL_KEY_AX_RECV:
+ case CADET_TUNNEL_KEY_AX_SENT:
+ case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT:
+ /* we're currently waiting for KX to complete, schedule job */
if (NULL == t->kx_task)
- {
t->kx_task
= GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
&retry_kx,
t);
- }
break;
case CADET_TUNNEL_KEY_OK:
+ if (GNUNET_YES == t->kx_auth_requested)
+ {
+ if (NULL != t->kx_task)
+ {
+ GNUNET_SCHEDULER_cancel (t->kx_task);
+ t->kx_task = NULL;
+ }
+ send_kx_auth (t,
+ &t->ax,
+ GNUNET_NO);
+ return;
+ }
try_send_normal_payload (t,
ct);
break;
@@ -1940,7 +2233,7 @@ consider_path_cb (void *cls,
if (ps == path)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Ignoring duplicate path %s for tunnel %s.\n",
+ "Ignoring duplicate path %s for %s.\n",
GCPP_2s (path),
GCT_2s (t));
return GNUNET_YES; /* duplicate */
@@ -1998,7 +2291,7 @@ consider_path_cb (void *cls,
ct);
t->num_connections++;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Found interesting path %s for tunnel %s, created connection %s\n",
+ "Found interesting path %s for %s, created %s\n",
GCPP_2s (path),
GCT_2s (t),
GCC_2s (ct->cc));
@@ -2026,7 +2319,7 @@ maintain_connections_cb (void *cls)
t->maintain_connections_task = NULL;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Performing connection maintenance for tunnel %s.\n",
+ "Performing connection maintenance for %s.\n",
GCT_2s (t));
(void) GCP_iterate_paths (t->destination,
@@ -2069,7 +2362,7 @@ handle_plaintext_keepalive (void *cls,
struct CadetTunnel *t = cls;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Received KEEPALIVE on tunnel %s\n",
+ "Received KEEPALIVE on %s\n",
GCT_2s (t));
GNUNET_STATISTICS_update (stats,
"# keepalives received",
@@ -2370,6 +2663,7 @@ GCT_create_tunnel (struct CadetPeer *destination)
GNUNET_MQ_handler_end ()
};
+ t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
new_ephemeral (&t->ax);
t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create ();
t->destination = destination;
@@ -2418,7 +2712,7 @@ GCT_add_inbound_connection (struct CadetTunnel *t,
if (NULL == ct->cc)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s refused inbound connection %s (duplicate)\n",
+ "%s refused inbound %s (duplicate)\n",
GCT_2s (t),
GCC_2s (ct->cc));
GNUNET_free (ct);
@@ -2433,7 +2727,7 @@ GCT_add_inbound_connection (struct CadetTunnel *t,
ct);
t->num_connections++;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s has new connection %s\n",
+ "%s has new %s\n",
GCT_2s (t),
GCC_2s (ct->cc));
return GNUNET_OK;
@@ -2456,7 +2750,7 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
ssize_t decrypted_size;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %s received %u bytes of encrypted data in state %d\n",
+ "%s received %u bytes of encrypted data in state %d\n",
GCT_2s (t),
(unsigned int) size,
t->estate);
@@ -2464,25 +2758,46 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
switch (t->estate)
{
case CADET_TUNNEL_KEY_UNINITIALIZED:
+ case CADET_TUNNEL_KEY_AX_RECV:
/* We did not even SEND our KX, how can the other peer
send us encrypted data? */
GNUNET_break_op (0);
return;
- case CADET_TUNNEL_KEY_SENT:
+ case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
+ /* We send KX, and other peer send KX to us at the same time.
+ Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
+ GNUNET_STATISTICS_update (stats,
+ "# received encrypted without KX_AUTH",
+ 1,
+ GNUNET_NO);
+ if (NULL != t->kx_task)
+ {
+ GNUNET_SCHEDULER_cancel (t->kx_task);
+ t->kx_task = NULL;
+ }
+ send_kx_auth (t,
+ &t->ax,
+ GNUNET_YES);
+ return;
+ case CADET_TUNNEL_KEY_AX_SENT:
/* We did not get the KX of the other peer, but that
- might have been lost. Ask for KX again. */
+ might have been lost. Send our KX again immediately. */
GNUNET_STATISTICS_update (stats,
"# received encrypted without KX",
1,
GNUNET_NO);
if (NULL != t->kx_task)
+ {
GNUNET_SCHEDULER_cancel (t->kx_task);
- t->kx_task = GNUNET_SCHEDULER_add_now (&retry_kx,
- t);
+ t->kx_task = NULL;
+ }
+ send_kx (t,
+ &t->ax);
return;
- case CADET_TUNNEL_KEY_PING:
- /* Great, first payload, we might graduate to OK */
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT:
+ /* Great, first payload, we might graduate to OK! */
case CADET_TUNNEL_KEY_OK:
+ /* We are up and running, all good. */
break;
}
@@ -2514,12 +2829,14 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
if (-1 != decrypted_size)
{
/* It worked! Treat this as authentication of the AX data! */
+ t->ax.DHRs = NULL; /* aliased with ax.DHRs */
+ t->ax.kx_0 = NULL; /* aliased with ax.DHRs */
cleanup_ax (&t->ax);
t->ax = *t->unverified_ax;
GNUNET_free (t->unverified_ax);
t->unverified_ax = NULL;
}
- if (CADET_TUNNEL_KEY_PING == t->estate)
+ if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
{
/* First time it worked, move tunnel into production! */
GCT_change_estate (t,
@@ -2544,6 +2861,8 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
t->unverified_attempts);
if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
{
+ t->unverified_ax->DHRs = NULL; /* aliased with ax.DHRs */
+ t->unverified_ax->kx_0 = NULL; /* aliased with ax.DHRs */
cleanup_ax (t->unverified_ax);
GNUNET_free (t->unverified_ax);
t->unverified_ax = NULL;
@@ -2555,7 +2874,7 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
/* Decryption failed for good, complain. */
GNUNET_break_op (0);
LOG (GNUNET_ERROR_TYPE_WARNING,
- "Tunnel %s failed to decrypt and validate encrypted data\n",
+ "%s failed to decrypt and validate encrypted data\n",
GCT_2s (t));
GNUNET_STATISTICS_update (stats,
"# unable to decrypt",
@@ -2602,7 +2921,7 @@ GCT_send (struct CadetTunnel *t,
}
payload_size = ntohs (message->size);
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypting %u bytes for tunnel %s\n",
+ "Encrypting %u bytes for %s\n",
(unsigned int) payload_size,
GCT_2s (t));
env = GNUNET_MQ_msg_extra (ax_msg,
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.h
b/src/cadet/gnunet-service-cadet-new_tunnels.h
index 09688eb70..2655f57f1 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.h
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.h
@@ -50,17 +50,30 @@ enum CadetTunnelEState
CADET_TUNNEL_KEY_UNINITIALIZED,
/**
- * Ephemeral key sent, waiting for peer's key.
+ * KX message sent, waiting for other peer's KX_AUTH.
*/
- CADET_TUNNEL_KEY_SENT,
+ CADET_TUNNEL_KEY_AX_SENT,
/**
- * Key received and we sent ours back, but we got no traffic yet.
+ * KX message received, trying to send back KX_AUTH.
+ */
+ CADET_TUNNEL_KEY_AX_RECV,
+
+ /**
+ * KX message sent and received, trying to send back KX_AUTH.
+ */
+ CADET_TUNNEL_KEY_AX_SENT_AND_RECV,
+
+ /**
+ * KX received and we sent KX_AUTH back, but we got no traffic yet,
+ * so we're waiting for either KX_AUTH or ENCRYPED traffic from
+ * the other peer.
+ *
* We will not yet send traffic, as this might have been a replay.
* The other (initiating) peer should send a CHANNEL_OPEN next
- * anyway.
+ * anyway, and then we are in business!
*/
- CADET_TUNNEL_KEY_PING,
+ CADET_TUNNEL_KEY_AX_AUTH_SENT,
/**
* Handshake completed: session key available.
@@ -307,6 +320,17 @@ GCT_handle_kx (struct CadetTConnection *ct,
/**
+ * Handle KX_AUTH message.
+ *
+ * @param ct connection/tunnel combo that received encrypted message
+ * @param msg the key exchange message
+ */
+void
+GCT_handle_kx_auth (struct CadetTConnection *ct,
+ const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
*msg);
+
+
+/**
* Handle encrypted message.
*
* @param ct connection/tunnel combo that received encrypted message
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c
b/src/cadet/gnunet-service-cadet_tunnel.c
index 3b21f4107..a94e8f4ff 100644
--- a/src/cadet/gnunet-service-cadet_tunnel.c
+++ b/src/cadet/gnunet-service-cadet_tunnel.c
@@ -499,10 +499,10 @@ estate2s (enum CadetTunnelEState es)
{
case CADET_TUNNEL_KEY_UNINITIALIZED:
return "CADET_TUNNEL_KEY_UNINITIALIZED";
- case CADET_TUNNEL_KEY_SENT:
- return "CADET_TUNNEL_KEY_SENT";
- case CADET_TUNNEL_KEY_PING:
- return "CADET_TUNNEL_KEY_PING";
+ case CADET_TUNNEL_KEY_AX_SENT:
+ return "CADET_TUNNEL_KEY_AX_SENT";
+ case CADET_TUNNEL_KEY_AX_AUTH_SENT:
+ return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
case CADET_TUNNEL_KEY_OK:
return "CADET_TUNNEL_KEY_OK";
case CADET_TUNNEL_KEY_REKEY:
@@ -534,7 +534,7 @@ is_ready (struct CadetTunnel *t)
conn_ok = CADET_TUNNEL_READY == t->cstate;
enc_ok = CADET_TUNNEL_KEY_OK == t->estate
|| CADET_TUNNEL_KEY_REKEY == t->estate
- || CADET_TUNNEL_KEY_PING == t->estate;
+ || CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate;
ready = conn_ok && enc_ok;
ready = ready || GCT_is_loopback (t);
return ready;
@@ -1486,7 +1486,7 @@ kx_resend (void *cls)
return;
}
- GCT_send_kx (t, CADET_TUNNEL_KEY_SENT >= t->estate);
+ GCT_send_kx (t, CADET_TUNNEL_KEY_AX_SENT >= t->estate);
}
@@ -1950,7 +1950,7 @@ GCT_handle_encrypted (struct CadetTunnel *t,
if (-1 == decrypted_size)
{
GNUNET_STATISTICS_update (stats, "# unable to decrypt", 1, GNUNET_NO);
- if (CADET_TUNNEL_KEY_PING <= t->estate)
+ if (CADET_TUNNEL_KEY_AX_AUTH_SENT <= t->estate)
{
GNUNET_break_op (0);
LOG (GNUNET_ERROR_TYPE_WARNING, "Wrong crypto, tunnel %s\n", GCT_2s (t));
@@ -2126,7 +2126,7 @@ GCT_handle_kx (struct CadetTunnel *t,
ax->Nr = 0;
ax->Ns = 0;
- GCT_change_estate (t, CADET_TUNNEL_KEY_PING);
+ GCT_change_estate (t, CADET_TUNNEL_KEY_AX_AUTH_SENT);
send_queued_data (t);
CADET_TIMING_END;
@@ -3251,7 +3251,7 @@ GCT_send_kx (struct CadetTunnel *t, int force_reply)
GCC_is_origin (c, GNUNET_YES),
GNUNET_YES, &ephm_sent, t);
if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
- GCT_change_estate (t, CADET_TUNNEL_KEY_SENT);
+ GCT_change_estate (t, CADET_TUNNEL_KEY_AX_SENT);
}
diff --git a/src/cadet/gnunet-service-cadet_tunnel.h
b/src/cadet/gnunet-service-cadet_tunnel.h
index 0abdc02ce..1b56a0632 100644
--- a/src/cadet/gnunet-service-cadet_tunnel.h
+++ b/src/cadet/gnunet-service-cadet_tunnel.h
@@ -87,7 +87,7 @@ enum CadetTunnelEState
/**
* Ephemeral key sent, waiting for peer's key.
*/
- CADET_TUNNEL_KEY_SENT,
+ CADET_TUNNEL_KEY_AX_SENT,
/**
* In OTR: New ephemeral key and ping sent, waiting for pong.
@@ -104,7 +104,7 @@ enum CadetTunnelEState
* traffic MUST be a complete channel creation 3-way handshake, no payload
* will be sent before confirmation.
*/
- CADET_TUNNEL_KEY_PING,
+ CADET_TUNNEL_KEY_AX_AUTH_SENT,
/**
* Handshake completed: session key available.
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index 9957d9021..f2e639e7a 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -19,7 +19,8 @@
*/
/**
* @file cadet/test_cadet.c
- *
+ * @author Bart Polot
+ * @author Christian Grothoff
* @brief Test for the cadet service: retransmission of traffic.
*/
#include <stdio.h>
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [gnunet] branch master updated: complete new KX implementation, including KX_AUTH defense against KX-injection based reset attacks,
gnunet <=