From 83e9890d6bfc08793a385904b6ddd66fc0037743 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Thu, 9 Jan 2014 20:55:45 -0500 Subject: [PATCH] Some work done on the client part. --- toxcore/onion_announce.c | 8 ++-- toxcore/onion_announce.h | 3 ++ toxcore/onion_client.c | 94 +++++++++++++++++++++++++++++++++++++++- toxcore/onion_client.h | 13 ++++-- 4 files changed, 110 insertions(+), 8 deletions(-) diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index fed3e798..feae88a4 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -31,8 +31,6 @@ #define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) #define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) -#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + crypto_box_MACBYTES) -#define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) #define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) #define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) @@ -252,8 +250,10 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet memcpy(pl + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); - uint8_t data[ANNOUNCE_RESPONSE_MAX_SIZE]; - len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); + uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; + len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), + data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); if ((uint32_t)len != ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) return 1; diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 2bc541a1..c314f55d 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -31,6 +31,9 @@ #define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + crypto_secretbox_MACBYTES) +#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + crypto_box_MACBYTES) +#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) + typedef struct { uint8_t public_key[crypto_box_PUBLICKEYBYTES]; IP_Port ret_ip_port; diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 80f0ab4e..a1a038da 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -25,12 +25,84 @@ #endif #include "onion_client.h" +#include "util.h" +#define ANNOUNCE_TIMEOUT 10 + +/* Creates a sendback for use in an announce request. + * Public key is the key we will be sending it to. + * + * sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big + * + * return -1 on failure + * return 0 on success + * + */ +static int new_sendback(Onion_Client *onion_c, uint8_t *public_key, uint8_t *sendback) +{ + uint8_t plain[sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES]; + uint64_t time = unix_time(); + memcpy(plain, &time, sizeof(uint64_t)); + memcpy(plain + sizeof(uint64_t), public_key, crypto_box_PUBLICKEYBYTES); + + int len = encrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, plain, sizeof(plain), + sendback + crypto_secretbox_NONCEBYTES); + + if ((uint32_t)len + crypto_secretbox_NONCEBYTES != ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) + return -1; + + return 0; +} + +/* Checks if the sendback is valid and returns the public key contained in it in returned_pubkey + * + * sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big + * returned_pubkey must be at least crypto_box_PUBLICKEYBYTES big + * + * return -1 on failure + * return 0 on success + */ +static int check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *returned_pubkey) +{ + uint8_t plain[sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES]; + int len = decrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, sendback + crypto_secretbox_NONCEBYTES, + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH - crypto_secretbox_NONCEBYTES, plain); + + if ((uint32_t)len != sizeof(plain)) + return -1; + + uint64_t timestamp; + memcpy(×tamp, plain, sizeof(uint64_t)); + uint64_t temp_time = unix_time(); + + if (timestamp + ANNOUNCE_TIMEOUT < temp_time || temp_time < timestamp) + return -1; + + memcpy(returned_pubkey, plain + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES); + return 0; +} static int handle_announce_response(void *object, IP_Port source, uint8_t *packet, uint32_t length) { Onion_Client *onion_c = object; + if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) + return 1; + + if ((length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) % sizeof(Node_format) != 0) + return 1; + + uint16_t num_nodes = (length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) / sizeof(Node_format); + + uint8_t public_key[crypto_box_PUBLICKEYBYTES]; + + if (check_sendback(onion_c, packet + 1, public_key) == -1) + return 1; + + uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; + + //int len = decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain); + //TODO return 0; } @@ -52,13 +124,32 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u int random_path(Onion_Client *onion_c, Node_format *nodes) { + return -1; +} +static void do_friend(Onion_Client *onion_c, uint16_t friendnum) +{ + + +} + +static void do_announce(Onion_Client *onion_c) +{ + uint32_t i; + + for (i = 0; i < MAX_ONION_CLIENTS; ++i) { + + } } void do_onion_client(Onion_Client *onion_c) { + uint32_t i; + do_announce(onion_c); - + for (i = 0; i < onion_c->num_friends; ++i) { + do_friend(onion_c, i); + } } Onion_Client *new_onion_client(DHT *dht) @@ -73,6 +164,7 @@ Onion_Client *new_onion_client(DHT *dht) onion_c->dht = dht; onion_c->net = dht->c->lossless_udp->net; + new_symmetric_key(onion_c->secret_symmetric_key); networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 92fc21ac..a5f72e82 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -29,9 +29,14 @@ #define MAX_ONION_CLIENTS 8 typedef struct { - Node_format clients_list[MAX_ONION_CLIENTS]; - + uint8_t client_id[CLIENT_ID_SIZE]; + IP_Port ip_port; + uint8_t ping_id[ONION_PING_ID_SIZE]; + uint64_t timestamp; +} Onion_Node; +typedef struct { + Onion_Node clients_list[MAX_ONION_CLIENTS]; } Onion_Friend; typedef struct { @@ -40,7 +45,9 @@ typedef struct { Onion_Friend *friends_list; uint16_t num_friends; - Node_format clients_annouce_list[MAX_ONION_CLIENTS]; + Onion_Node clients_announce_list[MAX_ONION_CLIENTS]; + + uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; } Onion_Client; int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id);