From 384750af8cf9e339989ded452181e1238ed6e307 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Wed, 23 Apr 2014 11:35:40 -0400 Subject: [PATCH] Major cleanups. Fixed circular dependency between DHT and net_crypto: DHT no longer depends on net_crypto. Moved the crypto request packets functions to crypto core and DHT. Cleaned up/added some defines that can be used to get the true maximum length of things like the friends request message. MAX_DATA_SIZE has been replaced in most places by more appropriate defines. --- toxcore/DHT.c | 67 ++++++++++++++++----- toxcore/DHT.h | 15 ++++- toxcore/Messenger.c | 29 +++++---- toxcore/Messenger.h | 6 +- toxcore/crypto_core.c | 71 +++++++++++++++++++++- toxcore/crypto_core.h | 31 ++++++++++ toxcore/friend_requests.c | 8 +-- toxcore/friend_requests.h | 5 +- toxcore/group_chats.c | 12 ++-- toxcore/net_crypto.c | 120 ++------------------------------------ toxcore/net_crypto.h | 41 +------------ toxcore/onion.c | 40 +++++++------ toxcore/onion.h | 7 +++ toxcore/onion_announce.c | 7 ++- toxcore/onion_announce.h | 5 ++ toxcore/onion_client.c | 47 +++++++-------- toxcore/onion_client.h | 7 ++- 17 files changed, 275 insertions(+), 243 deletions(-) diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 5b43cdb0..8b553581 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -1685,7 +1685,7 @@ int friend_ips(DHT *dht, IP_Port *ip_portlist, uint8_t *friend_id) static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) { uint8_t data[sizeof(uint64_t) + 1]; - uint8_t packet[MAX_DATA_SIZE]; + uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; int num = 0; @@ -1896,7 +1896,7 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8 if (length > HARDREQ_DATA_SIZE - 1) return -1; - uint8_t packet[MAX_DATA_SIZE]; + uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; uint8_t data[HARDREQ_DATA_SIZE] = {0}; data[0] = type; memcpy(data + 1, contents, length); @@ -1925,7 +1925,7 @@ static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *qu if (!ip_isset(&sendto->ip_port.ip)) return -1; - uint8_t packet[MAX_DATA_SIZE]; + uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; uint8_t data[1 + CLIENT_ID_SIZE + nodes_data_length]; data[0] = CHECK_TYPE_GETNODE_RES; memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); @@ -2242,12 +2242,54 @@ void do_hardening(DHT *dht) /*----------------------------------------------------------------------------------*/ -DHT *new_DHT(Net_Crypto *c) +void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object) +{ + dht->cryptopackethandlers[byte].function = cb; + dht->cryptopackethandlers[byte].object = object; +} + +static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) +{ + DHT *dht = object; + + if (packet[0] == NET_PACKET_CRYPTO) { + if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || + length > MAX_CRYPTO_REQUEST_SIZE + crypto_box_MACBYTES) + return 1; + + if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. + uint8_t public_key[crypto_box_PUBLICKEYBYTES]; + uint8_t data[MAX_CRYPTO_REQUEST_SIZE]; + uint8_t number; + int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length); + + if (len == -1 || len == 0) + return 1; + + if (!dht->cryptopackethandlers[number].function) return 1; + + return dht->cryptopackethandlers[number].function(dht->cryptopackethandlers[number].object, source, public_key, + data, len); + + } else { /* If request is not for us, try routing it. */ + int retval = route_packet(dht, packet + 1, packet, length); + + if ((unsigned int)retval == length) + return 0; + } + } + + return 1; +} + +/*----------------------------------------------------------------------------------*/ + +DHT *new_DHT(Networking_Core *net) { /* init time */ unix_time_update(); - if (c == NULL) + if (net == NULL) return NULL; DHT *dht = calloc(1, sizeof(DHT)); @@ -2255,8 +2297,7 @@ DHT *new_DHT(Net_Crypto *c) if (dht == NULL) return NULL; - dht->c = c; - dht->net = c->lossless_udp->net; + dht->net = net; dht->ping = new_ping(dht); if (dht->ping == NULL) { @@ -2266,9 +2307,9 @@ DHT *new_DHT(Net_Crypto *c) networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); - init_cryptopackets(dht); - cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); - cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); + networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht); + cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); + cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); new_symmetric_key(dht->secret_symmetric_key); crypto_box_keypair(dht->self_public_key, dht->self_secret_key); @@ -2283,7 +2324,6 @@ DHT *new_DHT(Net_Crypto *c) DHT_addfriend(dht, random_key_bytes); } - c->dht = dht; return dht; } @@ -2316,9 +2356,8 @@ void kill_DHT(DHT *dht) networking_registerhandler(dht->net, NET_PACKET_GET_NODES, NULL, NULL); networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, NULL, NULL); networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL); - cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_NAT_PING, NULL, NULL); - cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_HARDENING, NULL, NULL); - dht->c->dht = 0; + cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, NULL, NULL); + cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, NULL, NULL); kill_ping(dht->ping); free(dht->friends_list); free(dht); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 0c59dc81..c08b498c 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -24,7 +24,7 @@ #ifndef DHT_H #define DHT_H -#include "net_crypto.h" +#include "crypto_core.h" /* Size of the client_id in bytes. */ #define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES @@ -168,8 +168,15 @@ typedef struct { /*----------------------------------------------------------------------------------*/ +typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, + uint32_t len); + +typedef struct { + cryptopacket_handler_callback function; + void *object; +} Cryptopacket_Handles; + typedef struct { - Net_Crypto *c; Networking_Core *net; Client_data close_clientlist[LCLIENT_LIST]; @@ -193,6 +200,8 @@ typedef struct { struct Assoc *assoc; #endif uint64_t last_run; + + Cryptopacket_Handles cryptopackethandlers[256]; } DHT; /*----------------------------------------------------------------------------------*/ @@ -354,7 +363,7 @@ void DHT_save(DHT *dht, uint8_t *data); int DHT_load(DHT *dht, uint8_t *data, uint32_t length); /* Initialize DHT. */ -DHT *new_DHT(Net_Crypto *c); +DHT *new_DHT(Networking_Core *net); void kill_DHT(DHT *dht); diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index f7d773dd..308cf14e 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -214,9 +214,7 @@ void getaddress(Messenger *m, uint8_t *address) */ int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) { - if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES - + crypto_box_ZEROBYTES)) + if (length > MAX_FRIEND_REQUEST_DATA_SIZE) return FAERR_TOOLONG; uint8_t client_id[crypto_box_PUBLICKEYBYTES]; @@ -1757,26 +1755,26 @@ Messenger *new_messenger(uint8_t ipv6enabled) return NULL; } - m->net_crypto = new_net_crypto(m->net); + m->dht = new_DHT(m->net); - if (m->net_crypto == NULL) { + if (m->dht == NULL) { kill_networking(m->net); free(m); return NULL; } - m->dht = new_DHT(m->net_crypto); + m->net_crypto = new_net_crypto(m->dht); - if (m->dht == NULL) { - kill_net_crypto(m->net_crypto); + if (m->net_crypto == NULL) { kill_networking(m->net); + kill_DHT(m->dht); free(m); return NULL; } m->onion = new_onion(m->dht); m->onion_a = new_onion_announce(m->dht); - m->onion_c = new_onion_client(m->dht); + m->onion_c = new_onion_client(m->net_crypto); if (!(m->onion && m->onion_a && m->onion_c)) { kill_onion(m->onion); @@ -2409,10 +2407,12 @@ int wait_cleanup_messenger(Messenger *m, uint8_t *data) #define MESSENGER_STATE_TYPE_STATUSMESSAGE 5 #define MESSENGER_STATE_TYPE_STATUS 6 +#define SAVED_FRIEND_REQUEST_SIZE 1024 + struct SAVED_FRIEND { uint8_t status; uint8_t client_id[CLIENT_ID_SIZE]; - uint8_t info[MAX_DATA_SIZE]; // the data that is sent during the friend requests we do. + uint8_t info[SAVED_FRIEND_REQUEST_SIZE]; // the data that is sent during the friend requests we do. uint16_t info_size; // Length of the info. uint8_t name[MAX_NAME_LENGTH]; uint16_t name_length; @@ -2428,7 +2428,7 @@ struct SAVED_FRIEND { struct SAVED_FRIEND_OLD { uint8_t status; uint8_t client_id[CLIENT_ID_SIZE]; - uint8_t info[MAX_DATA_SIZE]; + uint8_t info[1024]; uint16_t info_size; uint8_t name[MAX_NAME_LENGTH]; uint16_t name_length; @@ -2456,7 +2456,12 @@ static uint32_t friends_list_save(Messenger *m, uint8_t *data) memcpy(temp.client_id, m->friendlist[i].client_id, CLIENT_ID_SIZE); if (temp.status < 3) { - memcpy(temp.info, m->friendlist[i].info, m->friendlist[i].info_size); + if (m->friendlist[i].info_size > SAVED_FRIEND_REQUEST_SIZE) { + memcpy(temp.info, m->friendlist[i].info, SAVED_FRIEND_REQUEST_SIZE); + } else { + memcpy(temp.info, m->friendlist[i].info, m->friendlist[i].info_size); + } + temp.info_size = htons(m->friendlist[i].info_size); temp.friendrequest_nospam = m->friendlist[i].friendrequest_nospam; } else { diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 0ce96f44..3d42e911 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -44,9 +44,9 @@ #define PACKET_ID_STATUSMESSAGE 49 #define PACKET_ID_USERSTATUS 50 #define PACKET_ID_TYPING 51 -#define PACKET_ID_RECEIPT 65 +#define PACKET_ID_RECEIPT 63 #define PACKET_ID_MESSAGE 64 -#define PACKET_ID_ACTION 63 +#define PACKET_ID_ACTION 65 #define PACKET_ID_MSI 69 #define PACKET_ID_FILE_SENDREQUEST 80 #define PACKET_ID_FILE_CONTROL 81 @@ -134,7 +134,7 @@ typedef struct { uint64_t friendrequest_lastsent; // Time at which the last friend request was sent. uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts. uint8_t status; // 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. - uint8_t info[MAX_DATA_SIZE]; // the data that is sent during the friend requests we do. + uint8_t info[MAX_FRIEND_REQUEST_DATA_SIZE]; // the data that is sent during the friend requests we do. uint8_t name[MAX_NAME_LENGTH]; uint16_t name_length; uint8_t name_sent; // 0 if we didn't send our name to this friend 1 if we have. diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 22612442..59053bc4 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -166,4 +166,73 @@ void new_nonce(uint8_t *nonce) increment_nonce(base_nonce); memcpy(nonce, base_nonce, crypto_box_NONCEBYTES); -} \ No newline at end of file +} + +/* Create a request to peer. + * send_public_key and send_secret_key are the pub/secret keys of the sender. + * recv_public_key is public key of reciever. + * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big. + * Data represents the data we send with the request with length being the length of the data. + * request_id is the id of the request (32 = friend request, 254 = ping request). + * + * return -1 on failure. + * return the length of the created packet on success. + */ +int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, + uint8_t *data, uint32_t length, uint8_t request_id) +{ + if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + + crypto_box_MACBYTES) + return -1; + + uint8_t nonce[crypto_box_NONCEBYTES]; + uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; + memcpy(temp + 1, data, length); + temp[0] = request_id; + new_nonce(nonce); + int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); + + if (len == -1) + return -1; + + packet[0] = NET_PACKET_CRYPTO; + memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); + memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); + memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); + + return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; +} + +/* Puts the senders public key in the request in public_key, the data from the request + * in data if a friend or ping request was sent to us and returns the length of the data. + * packet is the request packet and length is its length. + * + * return -1 if not valid request. + */ +int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, + uint8_t *request_id, uint8_t *packet, uint16_t length) +{ + if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES && + length <= MAX_CRYPTO_REQUEST_SIZE) { + if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { + memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); + uint8_t nonce[crypto_box_NONCEBYTES]; + uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; + memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); + int len1 = decrypt_data(public_key, self_secret_key, nonce, + packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, + length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); + + if (len1 == -1 || len1 == 0) + return -1; + + request_id[0] = temp[0]; + --len1; + memcpy(data, temp + 1, len1); + return len1; + } + } + + return -1; +} diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 6a13b22b..a862635e 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -25,6 +25,7 @@ #include "network.h" + /* return zero if the buffer contains only zeros. */ uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen); @@ -83,4 +84,34 @@ void new_symmetric_key(uint8_t *key); /*Gives a nonce guaranteed to be different from previous ones.*/ void new_nonce(uint8_t *nonce); +#define MAX_CRYPTO_REQUEST_SIZE 1024 + +#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ +#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */ +#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ +#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */ +#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */ +#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */ + +/* Create a request to peer. + * send_public_key and send_secret_key are the pub/secret keys of the sender. + * recv_public_key is public key of reciever. + * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big. + * Data represents the data we send with the request with length being the length of the data. + * request_id is the id of the request (32 = friend request, 254 = ping request). + * + * return -1 on failure. + * return the length of the created packet on success. + */ +int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, + uint8_t *data, uint32_t length, uint8_t request_id); + +/* puts the senders public key in the request in public_key, the data from the request + in data if a friend or ping request was sent to us and returns the length of the data. + packet is the request packet and length is its length + return -1 if not valid request. */ +int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, + uint8_t *request_id, uint8_t *packet, uint16_t length); + + #endif diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index c5cfa4b4..eb2a791c 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -37,10 +37,10 @@ */ int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) { - if (length + sizeof(nospam_num) >= MAX_DATA_SIZE) + if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) return -1; - uint8_t temp[MAX_DATA_SIZE]; + uint8_t temp[1 + sizeof(nospam_num) + length]; temp[0] = CRYPTO_PACKET_FRIEND_REQ; memcpy(temp + 1, &nospam_num, sizeof(nospam_num)); memcpy(temp + 1 + sizeof(nospam_num), data, length); @@ -50,7 +50,7 @@ int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nosp if (friend_num == -1) return -1; - int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length); + int num = send_onion_data(onion_c, friend_num, temp, sizeof(temp)); if (num <= 0) return -1; @@ -137,7 +137,7 @@ static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t { Friend_Requests *fr = object; - if (length <= 1 + sizeof(fr->nospam) || length > MAX_DATA_SIZE) + if (length <= 1 + sizeof(fr->nospam) || length > ONION_CLIENT_MAX_DATA_SIZE) return 1; ++packet; diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h index 8f25d4c1..429ffbad 100644 --- a/toxcore/friend_requests.h +++ b/toxcore/friend_requests.h @@ -26,6 +26,8 @@ #include "onion_client.h" +#define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t))) + typedef struct { uint32_t nospam; void (*handle_friendrequest)(void *, uint8_t *, uint8_t *, uint16_t, void *); @@ -46,7 +48,8 @@ typedef struct { } Friend_Requests; /* Try to send a friendrequest to peer with public_key. - * data is the data in the request and length is the length. + * data is the data in the request and length is the length. + * Maximum length of data is MAX_FRIEND_REQUEST_DATA_SIZE. */ int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); /* Set and get the nospam variable used to prevent one type of friend request spam. */ diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index ecc9cea7..fbe76d16 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -32,7 +32,7 @@ #include "LAN_discovery.h" #include "util.h" -#define GROUPCHAT_MAXDATA_LENGTH (MAX_DATA_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES)) +#define GROUPCHAT_MAXDATA_LENGTH (MAX_CRYPTO_REQUEST_SIZE - (1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES)) #define GROUPCHAT_MAXPLAINDATA_LENGTH (GROUPCHAT_MAXDATA_LENGTH - crypto_box_MACBYTES) #define GROUP_MAX_SENDNODES (GROUP_CLOSE_CONNECTIONS * 2) @@ -181,7 +181,7 @@ static int send_groupchatpacket(Group_Chat *chat, IP_Port ip_port, uint8_t *publ if (id_equal(chat->self_public_key, public_key)) return -1; - uint8_t packet[MAX_DATA_SIZE]; + uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; int len = create_request(chat->self_public_key, chat->self_secret_key, packet, public_key, data, length, request_id); packet[0] = NET_PACKET_GROUP_CHATS; @@ -587,10 +587,10 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id) { - if (len + GROUP_DATA_MIN_SIZE > MAX_DATA_SIZE) /*NOTE: not the real maximum len.*/ + if (len + GROUP_DATA_MIN_SIZE > MAX_CRYPTO_REQUEST_SIZE) /*NOTE: not the real maximum len.*/ return 1; - uint8_t packet[MAX_DATA_SIZE]; + uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; ++chat->message_number; if (chat->message_number == 0) @@ -616,11 +616,11 @@ static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t int handle_groupchatpacket(Group_Chat *chat, IP_Port source, uint8_t *packet, uint32_t length) { - if (length > MAX_DATA_SIZE) + if (length > MAX_CRYPTO_REQUEST_SIZE) return 1; uint8_t public_key[crypto_box_PUBLICKEYBYTES]; - uint8_t data[MAX_DATA_SIZE]; + uint8_t data[MAX_CRYPTO_REQUEST_SIZE]; uint8_t number; int len = handle_request(chat->self_public_key, chat->self_secret_key, public_key, data, &number, packet, length); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3eb9ca4c..2136e09f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -249,113 +249,6 @@ int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uin return 1; } -/* Create a request to peer. - * send_public_key and send_secret_key are the pub/secret keys of the sender. - * recv_public_key is public key of reciever. - * packet must be an array of MAX_DATA_SIZE big. - * Data represents the data we send with the request with length being the length of the data. - * request_id is the id of the request (32 = friend request, 254 = ping request). - * - * return -1 on failure. - * return the length of the created packet on success. - */ -int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, - uint8_t *data, uint32_t length, uint8_t request_id) -{ - if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES) - return -1; - - uint8_t nonce[crypto_box_NONCEBYTES]; - uint8_t temp[MAX_DATA_SIZE]; - memcpy(temp + 1, data, length); - temp[0] = request_id; - new_nonce(nonce); - int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1, - 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); - - if (len == -1) - return -1; - - packet[0] = NET_PACKET_CRYPTO; - memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES); - memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES); - memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); - - return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES; -} - -/* Puts the senders public key in the request in public_key, the data from the request - * in data if a friend or ping request was sent to us and returns the length of the data. - * packet is the request packet and length is its length. - * - * return -1 if not valid request. - */ -int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, - uint8_t *request_id, uint8_t *packet, uint16_t length) -{ - if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES && - length <= MAX_DATA_SIZE) { - if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { - memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); - uint8_t nonce[crypto_box_NONCEBYTES]; - uint8_t temp[MAX_DATA_SIZE]; - memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); - int len1 = decrypt_data(public_key, self_secret_key, nonce, - packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, - length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); - - if (len1 == -1 || len1 == 0) - return -1; - - request_id[0] = temp[0]; - --len1; - memcpy(data, temp + 1, len1); - return len1; - } - } - - return -1; -} - -void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object) -{ - c->cryptopackethandlers[byte].function = cb; - c->cryptopackethandlers[byte].object = object; -} - -static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) -{ - DHT *dht = object; - - if (packet[0] == NET_PACKET_CRYPTO) { - if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || - length > MAX_DATA_SIZE + crypto_box_MACBYTES) - return 1; - - if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. - uint8_t public_key[crypto_box_PUBLICKEYBYTES]; - uint8_t data[MAX_DATA_SIZE]; - uint8_t number; - int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length); - - if (len == -1 || len == 0) - return 1; - - if (!dht->c->cryptopackethandlers[number].function) return 1; - - return dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key, - data, len); - - } else { /* If request is not for us, try routing it. */ - int retval = route_packet(dht, packet + 1, packet, length); - - if ((unsigned int)retval == length) - return 0; - } - } - - return 1; -} /* Send a crypto handshake packet containing an encrypted secret nonce and session public key * to peer with connection_id and public_key. @@ -774,11 +667,11 @@ static void receive_crypto(Net_Crypto *c) /* Run this to (re)initialize net_crypto. * Sets all the global connection variables to their default values. */ -Net_Crypto *new_net_crypto(Networking_Core *net) +Net_Crypto *new_net_crypto(DHT *dht) { unix_time_update(); - if (net == NULL) + if (dht == NULL) return NULL; Net_Crypto *temp = calloc(1, sizeof(Net_Crypto)); @@ -786,7 +679,8 @@ Net_Crypto *new_net_crypto(Networking_Core *net) if (temp == NULL) return NULL; - temp->lossless_udp = new_lossless_udp(net); + temp->dht = dht; + temp->lossless_udp = new_lossless_udp(dht->net); if (temp->lossless_udp == NULL) { free(temp); @@ -798,12 +692,6 @@ Net_Crypto *new_net_crypto(Networking_Core *net) return temp; } -void init_cryptopackets(void *dht) -{ - DHT *s_dht = dht; - networking_registerhandler(s_dht->c->lossless_udp->net, NET_PACKET_CRYPTO, &cryptopacket_handle, s_dht); -} - static void kill_timedout(Net_Crypto *c) { uint32_t i; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index bbb9ee23..ef56b304 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -27,12 +27,6 @@ #include "Lossless_UDP.h" #include "DHT.h" -#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ -#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */ -#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ -#define CRYPTO_PACKET_GROUP_CHAT_GET_NODES 48 /* Group chat get Nodes packet */ -#define CRYPTO_PACKET_GROUP_CHAT_SEND_NODES 49 /* Group chat send Nodes packet */ -#define CRYPTO_PACKET_GROUP_CHAT_BROADCAST 50 /* Group chat broadcast packet */ #define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2) #define CRYPTO_CONN_NO_CONNECTION 0 @@ -58,13 +52,6 @@ typedef struct { } Crypto_Connection; -typedef int (*cryptopacket_handler_callback)(void *object, IP_Port ip_port, uint8_t *source_pubkey, uint8_t *data, - uint32_t len); - -typedef struct { - cryptopacket_handler_callback function; - void *object; -} Cryptopacket_Handles; typedef struct { Lossless_UDP *lossless_udp; @@ -79,9 +66,7 @@ typedef struct { uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; /* The secret key used for cookies */ - uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; - - Cryptopacket_Handles cryptopackethandlers[256]; + uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; } Net_Crypto; #include "DHT.h" @@ -102,26 +87,6 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) */ int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); -/* Create a request to peer. - * send_public_key and send_secret_key are the pub/secret keys of the sender. - * recv_public_key is public key of reciever. - * packet must be an array of MAX_DATA_SIZE big. - * Data represents the data we send with the request with length being the length of the data. - * request_id is the id of the request (32 = friend request, 254 = ping request). - * - * return -1 on failure. - * return the length of the created packet on success. - */ -int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, - uint8_t *data, uint32_t length, uint8_t request_id); - -/* puts the senders public key in the request in public_key, the data from the request - in data if a friend or ping request was sent to us and returns the length of the data. - packet is the request packet and length is its length - return -1 if not valid request. */ -int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, - uint8_t *request_id, uint8_t *packet, uint16_t length); - /* Function to call when request beginning with byte is received. */ void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object); @@ -186,15 +151,13 @@ void load_keys(Net_Crypto *c, uint8_t *keys); /* Create new instance of Net_Crypto. * Sets all the global connection variables to their default values. */ -Net_Crypto *new_net_crypto(Networking_Core *net); +Net_Crypto *new_net_crypto(DHT *dht); /* Main loop. */ void do_net_crypto(Net_Crypto *c); void kill_net_crypto(Net_Crypto *c); -/* Initialize the cryptopacket handling. */ -void init_cryptopackets(void *dht); #endif diff --git a/toxcore/onion.c b/toxcore/onion.c index c2ca21f8..8cc851c2 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -26,8 +26,6 @@ #include "onion.h" #include "util.h" -#define MAX_ONION_SIZE MAX_DATA_SIZE - #define RETURN_1 ONION_RETURN_1 #define RETURN_2 ONION_RETURN_2 #define RETURN_3 ONION_RETURN_3 @@ -89,13 +87,14 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes) /* Create and send a onion packet. * * Use Onion_Path path to send data of length to dest. + * Maximum length of data is ONION_MAX_DATA_SIZE. * * return -1 on failure. * return 0 on success. */ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length) { - if (1 + length + SEND_1 > MAX_ONION_SIZE || length == 0) + if (1 + length + SEND_1 > ONION_MAX_PACKET_SIZE || length == 0) return -1; to_net_family(&dest.ip); @@ -142,13 +141,18 @@ int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint return 0; } + /* Create and send a onion response sent initially to dest with. + * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE. * * return -1 on failure. * return 0 on success. */ int send_onion_response(Networking_Core *net, IP_Port dest, uint8_t *data, uint32_t length, uint8_t *ret) { + if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0) + return -1; + uint8_t packet[1 + RETURN_3 + length]; packet[0] = NET_PACKET_ONION_RECV_3; memcpy(packet + 1, ret, RETURN_3); @@ -164,7 +168,7 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui { Onion *onion = object; - if (length > MAX_ONION_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; if (length <= 1 + SEND_1) @@ -172,7 +176,7 @@ static int handle_send_initial(void *object, IP_Port source, uint8_t *packet, ui change_symmetric_key(onion); - uint8_t plain[MAX_ONION_SIZE]; + uint8_t plain[ONION_MAX_PACKET_SIZE]; uint8_t shared_key[crypto_box_BEFORENMBYTES]; get_shared_key(&onion->shared_keys_1, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES); int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, @@ -190,7 +194,7 @@ int onion_send_1(Onion *onion, uint8_t *plain, uint32_t len, IP_Port source, uin memcpy(&send_to, plain, sizeof(IP_Port)); to_host_family(&send_to.ip); - uint8_t data[MAX_ONION_SIZE]; + uint8_t data[ONION_MAX_PACKET_SIZE]; data[0] = NET_PACKET_ONION_SEND_1; memcpy(data + 1, nonce, crypto_box_NONCEBYTES); memcpy(data + 1 + crypto_box_NONCEBYTES, plain + sizeof(IP_Port), len - sizeof(IP_Port)); @@ -215,7 +219,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t { Onion *onion = object; - if (length > MAX_ONION_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; if (length <= 1 + SEND_2) @@ -223,7 +227,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t change_symmetric_key(onion); - uint8_t plain[MAX_ONION_SIZE]; + uint8_t plain[ONION_MAX_PACKET_SIZE]; uint8_t shared_key[crypto_box_BEFORENMBYTES]; get_shared_key(&onion->shared_keys_2, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES); int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, @@ -236,7 +240,7 @@ static int handle_send_1(void *object, IP_Port source, uint8_t *packet, uint32_t memcpy(&send_to, plain, sizeof(IP_Port)); to_host_family(&send_to.ip); - uint8_t data[MAX_ONION_SIZE]; + uint8_t data[ONION_MAX_PACKET_SIZE]; data[0] = NET_PACKET_ONION_SEND_2; memcpy(data + 1, packet + 1, crypto_box_NONCEBYTES); memcpy(data + 1 + crypto_box_NONCEBYTES, plain + sizeof(IP_Port), len - sizeof(IP_Port)); @@ -264,7 +268,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t { Onion *onion = object; - if (length > MAX_ONION_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; if (length <= 1 + SEND_3) @@ -272,7 +276,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t change_symmetric_key(onion); - uint8_t plain[MAX_ONION_SIZE]; + uint8_t plain[ONION_MAX_PACKET_SIZE]; uint8_t shared_key[crypto_box_BEFORENMBYTES]; get_shared_key(&onion->shared_keys_3, shared_key, onion->dht->self_secret_key, packet + 1 + crypto_box_NONCEBYTES); int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, @@ -285,7 +289,7 @@ static int handle_send_2(void *object, IP_Port source, uint8_t *packet, uint32_t memcpy(&send_to, plain, sizeof(IP_Port)); to_host_family(&send_to.ip); - uint8_t data[MAX_ONION_SIZE]; + uint8_t data[ONION_MAX_PACKET_SIZE]; memcpy(data, plain + sizeof(IP_Port), len - sizeof(IP_Port)); uint32_t data_len = (len - sizeof(IP_Port)); uint8_t *ret_part = data + (len - sizeof(IP_Port)); @@ -312,7 +316,7 @@ static int handle_recv_3(void *object, IP_Port source, uint8_t *packet, uint32_t { Onion *onion = object; - if (length > MAX_ONION_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; if (length <= 1 + RETURN_3) @@ -330,7 +334,7 @@ static int handle_recv_3(void *object, IP_Port source, uint8_t *packet, uint32_t IP_Port send_to; memcpy(&send_to, plain, sizeof(IP_Port)); - uint8_t data[MAX_ONION_SIZE]; + uint8_t data[ONION_MAX_PACKET_SIZE]; data[0] = NET_PACKET_ONION_RECV_2; memcpy(data + 1, plain + sizeof(IP_Port), RETURN_2); memcpy(data + 1 + RETURN_2, packet + 1 + RETURN_3, length - (1 + RETURN_3)); @@ -346,7 +350,7 @@ static int handle_recv_2(void *object, IP_Port source, uint8_t *packet, uint32_t { Onion *onion = object; - if (length > MAX_ONION_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; if (length <= 1 + RETURN_2) @@ -364,7 +368,7 @@ static int handle_recv_2(void *object, IP_Port source, uint8_t *packet, uint32_t IP_Port send_to; memcpy(&send_to, plain, sizeof(IP_Port)); - uint8_t data[MAX_ONION_SIZE]; + uint8_t data[ONION_MAX_PACKET_SIZE]; data[0] = NET_PACKET_ONION_RECV_1; memcpy(data + 1, plain + sizeof(IP_Port), RETURN_1); memcpy(data + 1 + RETURN_1, packet + 1 + RETURN_2, length - (1 + RETURN_2)); @@ -380,7 +384,7 @@ static int handle_recv_1(void *object, IP_Port source, uint8_t *packet, uint32_t { Onion *onion = object; - if (length > MAX_ONION_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; if (length <= 1 + RETURN_1) @@ -424,7 +428,7 @@ Onion *new_onion(DHT *dht) return NULL; onion->dht = dht; - onion->net = dht->c->lossless_udp->net; + onion->net = dht->net; new_symmetric_key(onion->secret_symmetric_key); onion->timestamp = unix_time(); diff --git a/toxcore/onion.h b/toxcore/onion.h index b15caad9..712bbf13 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -39,6 +39,8 @@ typedef struct { void *callback_object; } Onion; +#define ONION_MAX_PACKET_SIZE 1400 + #define ONION_RETURN_1 (crypto_box_NONCEBYTES + sizeof(IP_Port) + crypto_box_MACBYTES) #define ONION_RETURN_2 (crypto_box_NONCEBYTES + sizeof(IP_Port) + crypto_box_MACBYTES + ONION_RETURN_1) #define ONION_RETURN_3 (crypto_box_NONCEBYTES + sizeof(IP_Port) + crypto_box_MACBYTES + ONION_RETURN_2) @@ -48,6 +50,9 @@ typedef struct { #define ONION_SEND_2 (crypto_box_NONCEBYTES + ONION_SEND_BASE*2 + ONION_RETURN_1) #define ONION_SEND_1 (crypto_box_NONCEBYTES + ONION_SEND_BASE*3) +#define ONION_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1)) +#define ONION_RESPONSE_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (1 + ONION_RETURN_3)) + typedef struct { uint8_t shared_key1[crypto_box_BEFORENMBYTES]; uint8_t shared_key2[crypto_box_BEFORENMBYTES]; @@ -76,6 +81,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes); /* Create and send a onion packet. * * Use Onion_Path path to send data of length to dest. + * Maximum length of data is ONION_MAX_DATA_SIZE. * * return -1 on failure. * return 0 on success. @@ -83,6 +89,7 @@ int create_onion_path(DHT *dht, Onion_Path *new_path, Node_format *nodes); int send_onion_packet(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *data, uint32_t length); /* Create and send a onion response sent initially to dest with. + * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE. * * return -1 on failure. * return 0 on success. diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 5bab931a..1e73aef9 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -32,7 +32,7 @@ #define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) #define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) -#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE #define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) /* Create and send an onion announce request packet. @@ -90,6 +90,9 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length) { + if (DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE) + return -1; + uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; packet[0] = NET_PACKET_ONION_DATA_REQUEST; memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); @@ -304,7 +307,7 @@ static int handle_data_request(void *object, IP_Port source, uint8_t *packet, ui if (length <= DATA_REQUEST_MIN_SIZE_RECV) return 1; - if (length >= MAX_DATA_SIZE) + if (length > ONION_MAX_PACKET_SIZE) return 1; int index = in_entries(onion_a, packet + 1); diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 071dc9ff..dff61e99 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -40,6 +40,9 @@ #error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES #endif +#define ONION_DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +#define MAX_DATA_REQUEST_SIZE (ONION_MAX_DATA_SIZE - ONION_DATA_REQUEST_MIN_SIZE) + typedef struct { uint8_t public_key[crypto_box_PUBLICKEYBYTES]; IP_Port ret_ip_port; @@ -86,6 +89,8 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de * * nonce is the nonce to encrypt this packet with * + * The maximum length of data is MAX_DATA_REQUEST_SIZE. + * * return -1 on failure. * return 0 on success. */ diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index fbb00a2c..35fb4423 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -183,9 +183,9 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ if (random_path(onion_c->dht, &onion_c->onion_paths, pathnum, &path) == -1) return -1; - return send_announce_request(onion_c->net, &path, dest_node, onion_c->dht->c->self_public_key, - onion_c->dht->c->self_secret_key, ping_id, - onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback); + return send_announce_request(onion_c->net, &path, dest_node, onion_c->c->self_public_key, + onion_c->c->self_secret_key, ping_id, + onion_c->c->self_public_key, onion_c->temp_public_key, sendback); } else { if (random_path(onion_c->dht, &onion_c->friends_list[num - 1].onion_paths, pathnum, &path) == -1) return -1; @@ -236,7 +236,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ if (num == 0) { list_nodes = onion_c->clients_announce_list; - reference_id = onion_c->dht->c->self_public_key; + reference_id = onion_c->c->self_public_key; if (is_stored && memcmp(pingid_or_key, onion_c->temp_public_key, crypto_box_PUBLICKEYBYTES) != 0) { is_stored = 0; @@ -325,7 +325,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n if (num == 0) { list_nodes = onion_c->clients_announce_list; - reference_id = onion_c->dht->c->self_public_key; + reference_id = onion_c->c->self_public_key; ping_nodes_sent_second = &onion_c->ping_nodes_sent_second; last_pinged = onion_c->last_pinged; last_pinged_index = &onion_c->last_pinged_index; @@ -388,7 +388,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe int len = -1; if (num == 0) { - len = decrypt_data(public_key, onion_c->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, + len = decrypt_data(public_key, onion_c->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain); } else { @@ -421,7 +421,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe return 0; } -#define DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +#define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE static int handle_data_response(void *object, IP_Port source, uint8_t *packet, uint32_t length) { @@ -430,7 +430,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u if (length <= (ONION_DATA_RESPONSE_MIN_SIZE + DATA_IN_RESPONSE_MIN_SIZE)) return 1; - if (length > MAX_DATA_SIZE) + if (length > MAX_DATA_REQUEST_SIZE) return 1; uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE]; @@ -442,7 +442,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u return 1; uint8_t plain[sizeof(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE]; - len = decrypt_data(temp_plain, onion_c->dht->c->self_secret_key, packet + 1, temp_plain + crypto_box_PUBLICKEYBYTES, + len = decrypt_data(temp_plain, onion_c->c->self_secret_key, packet + 1, temp_plain + crypto_box_PUBLICKEYBYTES, sizeof(temp_plain) - crypto_box_PUBLICKEYBYTES, plain); if ((uint32_t)len != sizeof(plain)) @@ -527,7 +527,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32 if ((uint32_t)friend_num >= onion_c->num_friends) return -1; - if (length + DATA_IN_RESPONSE_MIN_SIZE + ONION_DATA_RESPONSE_MIN_SIZE + ONION_SEND_1 > MAX_DATA_SIZE) + if (length + DATA_IN_RESPONSE_MIN_SIZE > MAX_DATA_REQUEST_SIZE) return -1; if (length == 0) @@ -537,8 +537,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32 random_nonce(nonce); uint8_t packet[DATA_IN_RESPONSE_MIN_SIZE + length]; - memcpy(packet, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES); - int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data, + memcpy(packet, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES); + int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data, length, packet + crypto_box_PUBLICKEYBYTES); if ((uint32_t)len + crypto_box_PUBLICKEYBYTES != sizeof(packet)) @@ -597,15 +597,15 @@ static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, new_nonce(nonce); uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length]; - memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES); + memcpy(temp, onion_c->c->self_public_key, crypto_box_PUBLICKEYBYTES); memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); - int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data, + int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->c->self_secret_key, nonce, data, length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp)) return -1; - uint8_t packet[MAX_DATA_SIZE]; + uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet, onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID); @@ -626,7 +626,7 @@ static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubke return 1; uint8_t plain[FAKEID_DATA_MAX_LENGTH]; - int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES, + int len = decrypt_data(packet, onion_c->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES, packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain); @@ -960,7 +960,7 @@ static void do_announce(Onion_Client *onion_c) if (count != MAX_ONION_CLIENTS) { if (count < (uint32_t)rand() % MAX_ONION_CLIENTS) { Node_format nodes_list[MAX_SENT_NODES]; - uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list, + uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->c->self_public_key, nodes_list, rand() % 2 ? AF_INET : AF_INET6, 1, 0); for (i = 0; i < num_nodes; ++i) { @@ -989,9 +989,9 @@ void do_onion_client(Onion_Client *onion_c) onion_c->last_run = unix_time(); } -Onion_Client *new_onion_client(DHT *dht) +Onion_Client *new_onion_client(Net_Crypto *c) { - if (dht == NULL) + if (c == NULL) return NULL; Onion_Client *onion_c = calloc(1, sizeof(Onion_Client)); @@ -999,14 +999,15 @@ Onion_Client *new_onion_client(DHT *dht) if (onion_c == NULL) return NULL; - onion_c->dht = dht; - onion_c->net = dht->c->lossless_udp->net; + onion_c->dht = c->dht; + onion_c->net = c->dht->net; + onion_c->c = c; new_symmetric_key(onion_c->secret_symmetric_key); crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_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); oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); - cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c); + cryptopacket_registerhandler(onion_c->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c); return onion_c; } @@ -1020,7 +1021,7 @@ void kill_onion_client(Onion_Client *onion_c) networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); oniondata_registerhandler(onion_c, FAKEID_DATA_ID, NULL, NULL); - cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, NULL, NULL); + cryptopacket_registerhandler(onion_c->c, FAKEID_DATA_ID, NULL, NULL); memset(onion_c, 0, sizeof(Onion_Client)); free(onion_c); } diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 8e09b63a..6b960e40 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -25,6 +25,7 @@ #define ONION_CLIENT_H #include "onion_announce.h" +#include "net_crypto.h" #define MAX_ONION_CLIENTS 8 #define ONION_NODE_PING_INTERVAL 30 @@ -105,6 +106,7 @@ typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, typedef struct { DHT *dht; + Net_Crypto *c; Networking_Core *net; Onion_Friend *friends_list; uint16_t num_friends; @@ -170,8 +172,11 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on */ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); +#define ONION_DATA_IN_RESPONSE_MIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE) /* Send data of length length to friendnum. + * Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE. * This data will be recieved by the friend using the Onion_Data_Handlers callbacks. * * Even if this function succeeds, the friend might not recieve any data. @@ -186,7 +191,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha void do_onion_client(Onion_Client *onion_c); -Onion_Client *new_onion_client(DHT *dht); +Onion_Client *new_onion_client(Net_Crypto *c); void kill_onion_client(Onion_Client *onion_c);