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.
This commit is contained in:
irungentoo 2014-04-23 11:35:40 -04:00
parent 1bfe15ee88
commit 384750af8c
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
17 changed files with 275 additions and 243 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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. */

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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.

View File

@ -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);

View File

@ -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.
*/

View File

@ -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);
}

View File

@ -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);