*/
struct CadetPeer
{
- /**
- * ID of the peer
- */
+ /**
+ * ID of the peer
+ */
GNUNET_PEER_Id id;
- /**
- * Axolotl permanent public key.
- */
- struct GNUNET_CRYPTO_EcdhePublicKey ax_key;
-
- /**
- * Last time we heard from this peer
- */
+ /**
+ * Last time we heard from this peer
+ */
struct GNUNET_TIME_Absolute last_contact;
- /**
- * Paths to reach the peer, ordered by ascending hop count
- */
+ /**
+ * Paths to reach the peer, ordered by ascending hop count
+ */
struct CadetPeerPath *path_head;
- /**
- * Paths to reach the peer, ordered by ascending hop count
- */
+ /**
+ * Paths to reach the peer, ordered by ascending hop count
+ */
struct CadetPeerPath *path_tail;
- /**
- * Handle to stop the DHT search for paths to this peer
- */
+ /**
+ * Handle to stop the DHT search for paths to this peer
+ */
struct GCD_search_handle *search_h;
/**
}
-/**
- * Check if the given ECDH key is correct for the peer.
- *
- * This function caches the results if the key has been previoulsy checked,
- * otherwise checks that the key is signed with the peer's ID (EdDSA key).
- *
- * TODO: save the cached public key to permanent storage / peerinfo.
- *
- * @param peer Peer whose key to check.
- * @param key ECDH key to check.
- * @param purpose Purpose of the signature (followed by the key).
- * @param sig Signature with the peer's EdDSA key (PeerID).
- */
-int
-GCP_check_key (struct CadetPeer *peer,
- const struct GNUNET_CRYPTO_EcdhePublicKey *key,
- const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- const struct GNUNET_CRYPTO_EddsaSignature *sig)
-{
- struct GNUNET_CRYPTO_EddsaPublicKey *pub;
- int verified;
-
- /* Is it the same as the cached key? */
- if (0 == memcmp (&peer->ax_key, key, sizeof (*key)))
- return GNUNET_OK;
-
- /* New key, verify. */
- pub = (struct GNUNET_CRYPTO_EddsaPublicKey *) GCP_get_id (peer);
- verified = GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_CADET_AXKX,
- purpose, sig, pub);
-
- if (GNUNET_OK != verified)
- return GNUNET_SYSERR;
-
- /* Cache key for later. */
- peer->ax_key = *key;
- return GNUNET_OK;
-}
-
-
-/**
- * Get the Identity ECDH key of the peer.
- *
- * @param peer Peer whose key to get.
- *
- * @return Peer's permanent ECDH key (might be all 0: unknown).
- *
- */
-struct GNUNET_CRYPTO_EcdhePublicKey *
-GCP_get_ecdh_key (struct CadetPeer *peer)
-{
- return &peer->ax_key;
-}
-
-
/**
* Notify a peer that a link between two other peers is broken. If any path
* used that link, eliminate it.
void
GCP_try_connect (struct CadetPeer *peer);
-/**
- * Check if the given ECDH key is correct for the peer.
- *
- * This function caches the results if the key has been previoulsy checked,
- * otherwise checks that the key is signed with the peer's ID (EdDSA key).
- *
- * TODO: save the cached public key to permanent storage / peerinfo.
- *
- * @param peer Peer whose key to check.
- * @param key ECDH key to check.
- * @param purpose Purpose of the signature (followed by the key).
- * @param sig Signature with the peer's EdDSA key (PeerID).
- */
-int
-GCP_check_key (struct CadetPeer *peer,
- const struct GNUNET_CRYPTO_EcdhePublicKey *key,
- const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- const struct GNUNET_CRYPTO_EddsaSignature *sig);
-
-/**
- * Get the Identity ECDH key of the peer.
- *
- * @param peer Peer whose key to get.
- *
- * @return Peer's permanent ECDH key (might be all 0: unknown).
- */
-struct GNUNET_CRYPTO_EddsaPublicKey *
-GCP_get_key (struct CadetPeer *peer);
-
/**
* Notify a peer that a link between two other peers is broken. If any path
* used that link, eliminate it.
*/
struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0;
- /**
- * ECDH Identity key (recv).
- */
- struct GNUNET_CRYPTO_EcdhePublicKey DHIr;
-
/**
* ECDH Ratchet key (send).
*/
};
-/**
- * Cached Axolotl key with signature.
- */
-struct CadetAxolotlSignedKey
-{
- /**
- * Information about what is being signed (@a permanent_key).
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Permanent public ECDH key.
- */
- struct GNUNET_CRYPTO_EcdhePublicKey permanent_key;
-
- /**
- * An EdDSA signature of the permanent ECDH key with the Peer's ID key.
- */
- struct GNUNET_CRYPTO_EddsaSignature signature;
-} GNUNET_PACKED;
-
-
/******************************************************************************/
/******************************* GLOBALS ***********************************/
/******************************************************************************/
/******************************** AXOLOTL ************************************/
-static struct GNUNET_CRYPTO_EcdhePrivateKey *ax_key;
-
-/**
- * Own Axolotl permanent public key (cache).
- */
-static struct CadetAxolotlSignedKey ax_identity;
-
/**
* How many messages are needed to trigger a ratchet advance.
*/
}
-/**
- * Ephemeral key message purpose size.
- *
- * @return Size of the part of the ephemeral key message that must be signed.
- */
-static size_t
-ax_purpose_size (void)
-{
- return sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
- sizeof (struct GNUNET_CRYPTO_EcdhePublicKey);
-}
-
-
/**
* Size of the encrypted part of a ping message.
*
struct CadetTunnelAxolotl *ax;
struct GNUNET_HashCode key_material[3];
struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
- const struct GNUNET_CRYPTO_EcdhePublicKey *pub;
- const struct GNUNET_CRYPTO_EcdhePrivateKey *priv;
const char salt[] = "CADET Axolotl salt";
const struct GNUNET_PeerIdentity *pid;
int am_I_alice;
return;
}
- if (GNUNET_OK != GCP_check_key (t->peer, &msg->permanent_key,
- &msg->purpose, &msg->signature))
- {
- GNUNET_break_op (0);
- return;
- }
-
pid = GCT_get_destination (t);
if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, pid))
am_I_alice = GNUNET_YES;
ax = t->ax;
ax->DHRr = msg->ratchet_key;
- ax->DHIr = msg->permanent_key;
/* ECDH A B0 */
if (GNUNET_YES == am_I_alice)
{
- priv = ax_key; /* A */
- pub = &msg->ephemeral_key; /* B0 */
+ GNUNET_CRYPTO_eddsa_ecdh (id_key, /* A */
+ &msg->ephemeral_key, /* B0 */
+ &key_material[0]);
}
else
{
- priv = ax->kx_0; /* B0 */
- pub = &ax->DHIr; /* A */
+ GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* B0 */
+ &pid->public_key, /* A */
+ &key_material[0]);
}
- GNUNET_CRYPTO_ecc_ecdh (priv, pub, &key_material[0]);
/* ECDH A0 B */
if (GNUNET_YES == am_I_alice)
{
- priv = ax->kx_0; /* A0 */
- pub = &ax->DHIr; /* B */
+ GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* A0 */
+ &pid->public_key, /* B */
+ &key_material[1]);
}
else
{
- priv = ax_key; /* B */
- pub = &msg->ephemeral_key; /* A0 */
+ GNUNET_CRYPTO_eddsa_ecdh (id_key, /* A */
+ &msg->ephemeral_key, /* B0 */
+ &key_material[1]);
+
+
}
- GNUNET_CRYPTO_ecc_ecdh (priv, pub, &key_material[1]);
- /* ECDH A0 B0*/
- priv = ax->kx_0; /* A0 or B0 */
- pub = &msg->ephemeral_key; /* B0 or A0 */
- GNUNET_CRYPTO_ecc_ecdh (priv, pub, &key_material[2]);
+ /* ECDH A0 B0 */
+ /* (This is the triple-DH, we could probably safely skip this,
+ as A0/B0 are already in the key material.) */
+ GNUNET_CRYPTO_ecc_ecdh (ax->kx_0, /* A0 or B0 */
+ &msg->ephemeral_key, /* B0 or A0 */
+ &key_material[2]);
#if DUMP_KEYS_TO_STDERR
{
size_t payload_size;
int decrypted_size;
uint16_t type;
- struct GNUNET_MessageHeader *msgh;
+ const struct GNUNET_MessageHeader *msgh;
unsigned int off;
type = ntohs (msg->type);
otr_kx_msg.purpose.size = htonl (ephemeral_purpose_size ());
otr_kx_msg.origin_identity = my_full_id;
rekey_task = GNUNET_SCHEDULER_add_now (&global_otr_rekey, NULL);
-
- ax_key = GNUNET_CRYPTO_ecdhe_key_create ();
- GNUNET_CRYPTO_ecdhe_key_get_public (ax_key, &ax_identity.permanent_key);
- ax_identity.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CADET_AXKX);
- ax_identity.purpose.size = htonl (ax_purpose_size ());
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign (id_key,
- &ax_identity.purpose,
- &ax_identity.signature));
-
tunnels = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES);
}
}
GNUNET_CONTAINER_multipeermap_iterate (tunnels, &destroy_iterator, NULL);
GNUNET_CONTAINER_multipeermap_destroy (tunnels);
- GNUNET_free (ax_key);
}
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_AX_KX);
msg.force_reply = htonl (force_reply);
- msg.permanent_key = ax_identity.permanent_key;
- msg.purpose = ax_identity.purpose;
- msg.signature = ax_identity.signature;
GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->kx_0, &msg.ephemeral_key);
GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &msg.ratchet_key);
LOG2 (level, "TTT CKr\t %s\n",
GNUNET_h2s ((struct GNUNET_HashCode *) &ax->CKr));
- GNUNET_CRYPTO_ecdhe_key_get_public (ax_key, &pub);
- LOG2 (level, "TTT DHIs\t %s\n",
- GNUNET_h2s ((struct GNUNET_HashCode *) &pub));
- LOG2 (level, "TTT DHIr\t %s\n",
- GNUNET_h2s ((struct GNUNET_HashCode *) &ax->DHIr));
GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, &pub);
LOG2 (level, "TTT DHRs\t %s\n",
GNUNET_h2s ((struct GNUNET_HashCode *) &pub));