Skip to content

Commit

Permalink
Major cleanups.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
irungentoo committed Apr 23, 2014
1 parent 1bfe15e commit 384750a
Show file tree
Hide file tree
Showing 17 changed files with 275 additions and 243 deletions.
67 changes: 53 additions & 14 deletions toxcore/DHT.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -2242,21 +2242,62 @@ 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));

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) {
Expand All @@ -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);
Expand All @@ -2283,7 +2324,6 @@ DHT *new_DHT(Net_Crypto *c)
DHT_addfriend(dht, random_key_bytes);
}

c->dht = dht;
return dht;
}

Expand Down Expand Up @@ -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);
Expand Down
15 changes: 12 additions & 3 deletions toxcore/DHT.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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];
Expand All @@ -193,6 +200,8 @@ typedef struct {
struct Assoc *assoc;
#endif
uint64_t last_run;

Cryptopacket_Handles cryptopackethandlers[256];
} DHT;
/*----------------------------------------------------------------------------------*/

Expand Down Expand Up @@ -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);

Expand Down
29 changes: 17 additions & 12 deletions toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions toxcore/Messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
71 changes: 70 additions & 1 deletion toxcore/crypto_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,73 @@ void new_nonce(uint8_t *nonce)

increment_nonce(base_nonce);
memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
}
}

/* 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;
}
31 changes: 31 additions & 0 deletions toxcore/crypto_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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

0 comments on commit 384750a

Please sign in to comment.