Skip to content

Commit

Permalink
Add backwards compatibility code for onion
Browse files Browse the repository at this point in the history
  • Loading branch information
JFreegman committed May 28, 2020
1 parent c871805 commit f3fef6a
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 5 deletions.
10 changes: 8 additions & 2 deletions toxcore/network.h
Expand Up @@ -119,6 +119,9 @@ typedef enum Net_Packet_Type {
NET_PACKET_ONION_RECV_2 = 0x9c,
NET_PACKET_ONION_RECV_1 = 0x9d,

NET_PACKET_ANNOUNCE_REQUEST_LEG = 0x96, /* TODO: DEPRECATE */
NET_PACKET_ANNOUNCE_RSPONSE_LEG = 0x97, /* TODO: DEPRECATE */

BOOTSTRAP_INFO_PACKET_ID = 0xf1, /* Only used for bootstrap nodes */

NET_PACKET_MAX = 0xff, /* This type must remain within a single uint8. */
Expand Down Expand Up @@ -150,15 +153,18 @@ typedef enum Net_Packet_Type {
NET_PACKET_ONION_SEND_1 = 0x81,
NET_PACKET_ONION_SEND_2 = 0x82,

NET_PACKET_ANNOUNCE_REQUEST = 0x83,
NET_PACKET_ANNOUNCE_RESPONSE = 0x84,
NET_PACKET_ONION_DATA_REQUEST = 0x85,
NET_PACKET_ONION_DATA_RESPONSE = 0x86,
NET_PACKET_ANNOUNCE_REQUEST = 0x87,
NET_PACKET_ANNOUNCE_RESPONSE = 0x88,

NET_PACKET_ONION_RECV_3 = 0x8c,
NET_PACKET_ONION_RECV_2 = 0x8d,
NET_PACKET_ONION_RECV_1 = 0x8e,

NET_PACKET_ANNOUNCE_REQUEST_LEG = 0x83, /* TODO: DEPRECATE */
NET_PACKET_ANNOUNCE_RSPONSE_LEG = 0x84, /* TODO: DEPRECATE */

BOOTSTRAP_INFO_PACKET_ID = 0xf0, /* Only used for bootstrap nodes */

NET_PACKET_MAX = 0xff, /* This type must remain within a single uint8. */
Expand Down
4 changes: 3 additions & 1 deletion toxcore/onion.c
Expand Up @@ -468,7 +468,9 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}

if (plain[SIZE_IPPORT] != NET_PACKET_ANNOUNCE_REQUEST &&
uint8_t packet_id = plain[SIZE_IPPORT];

if (!(packet_id == NET_PACKET_ANNOUNCE_REQUEST || packet_id == NET_PACKET_ANNOUNCE_REQUEST_LEG) &&
plain[SIZE_IPPORT] != NET_PACKET_ONION_DATA_REQUEST) {
return 1;
}
Expand Down
109 changes: 108 additions & 1 deletion toxcore/onion_announce.c
Expand Up @@ -24,6 +24,9 @@
#define ANNOUNCE_REQUEST_MIN_SIZE_RECV (ONION_ANNOUNCE_REQUEST_MIN_SIZE + ONION_RETURN_3)
#define ANNOUNCE_REQUEST_MAX_SIZE_RECV (ONION_ANNOUNCE_REQUEST_MAX_SIZE + ONION_RETURN_3)

/* TODO: DEPRECATE */
#define ANNOUNCE_REQUEST_SIZE_RECV (ONION_ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)

#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE
#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3)

Expand Down Expand Up @@ -86,7 +89,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
memcpy(plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE, &sendback_data,
sizeof(sendback_data));

packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
packet[0] = NET_PACKET_ANNOUNCE_REQUEST_LEG;
random_nonce(packet + 1);

int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
Expand Down Expand Up @@ -641,6 +644,107 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
return 0;
}

/* TODO: DEPRECATE */
static int handle_announce_request_leg(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion_Announce *onion_a = (Onion_Announce *)object;

if (length != ANNOUNCE_REQUEST_SIZE_RECV) {
return 1;
}

const uint8_t *packet_public_key = packet + 1 + CRYPTO_NONCE_SIZE;
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
get_shared_key(onion_a->mono_time, &onion_a->shared_keys_recv, shared_key, dht_get_self_secret_key(onion_a->dht),
packet_public_key);

uint8_t plain[ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE +
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH +
CRYPTO_MAC_SIZE, plain);

if ((uint32_t)len != sizeof(plain)) {
return 1;
}

uint8_t ping_id1[ONION_PING_ID_SIZE];
generate_ping_id(onion_a, mono_time_get(onion_a->mono_time), packet_public_key, source, ping_id1);

uint8_t ping_id2[ONION_PING_ID_SIZE];
generate_ping_id(onion_a, mono_time_get(onion_a->mono_time) + PING_ID_TIMEOUT, packet_public_key, source, ping_id2);

int index;

uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE;

if (crypto_memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0
|| crypto_memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
index = add_to_entries(onion_a, source, packet_public_key, data_public_key,
packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
} else {
index = in_entries(onion_a, plain + ONION_PING_ID_SIZE);
}

/*Respond with a announce response packet*/
Node_format nodes_list[MAX_SENT_NODES];
unsigned int num_nodes =
get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec, ip_is_lan(source.ip), 1);
uint8_t nonce[CRYPTO_NONCE_SIZE];
random_nonce(nonce);

uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)];

if (index == -1) {
pl[0] = 0;
memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
} else {
if (public_key_cmp(onion_a->entries[index].public_key, packet_public_key) == 0) {
if (public_key_cmp(onion_a->entries[index].data_public_key, data_public_key) != 0) {
pl[0] = 0;
memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
} else {
pl[0] = 2;
memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
}
} else {
pl[0] = 1;
memcpy(pl + 1, onion_a->entries[index].data_public_key, CRYPTO_PUBLIC_KEY_SIZE);
}
}

int nodes_length = 0;

if (num_nodes != 0) {
nodes_length = pack_nodes(pl + 1 + ONION_PING_ID_SIZE, sizeof(nodes_list), nodes_list, num_nodes);

if (nodes_length <= 0) {
return 1;
}
}

uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
len = encrypt_data_symmetric(shared_key, nonce, pl, 1 + ONION_PING_ID_SIZE + nodes_length,
data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE);

if (len != 1 + ONION_PING_ID_SIZE + nodes_length + CRYPTO_MAC_SIZE) {
return 1;
}

data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
memcpy(data + 1, plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, CRYPTO_NONCE_SIZE);

if (send_onion_response(onion_a->net, source, data,
1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)) == -1) {
return 1;
}

return 0;
}

static int handle_data_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion_Announce *onion_a = (Onion_Announce *)object;
Expand Down Expand Up @@ -699,6 +803,7 @@ Onion_Announce *new_onion_announce(Mono_Time *mono_time, DHT *dht, GC_Announces_

networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_announce_request, onion_a);
networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, &handle_data_request, onion_a);
networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST_LEG, &handle_announce_request_leg, onion_a);

return onion_a;
}
Expand All @@ -710,6 +815,8 @@ void kill_onion_announce(Onion_Announce *onion_a)
}

networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, nullptr, nullptr);
networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST_LEG, nullptr, nullptr);
networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, nullptr, nullptr);
free(onion_a);
}

4 changes: 3 additions & 1 deletion toxcore/onion_announce.h
Expand Up @@ -25,6 +25,9 @@
#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (2 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + ONION_PING_ID_SIZE + CRYPTO_MAC_SIZE)
#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + GCA_ANNOUNCE_MAX_SIZE * MAX_SENT_NODES)

/* TODO: DEPRECATE */
#define ONION_ANNOUNCE_REQUEST_SIZE (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_MAC_SIZE)

#define ONION_DATA_RESPONSE_MIN_SIZE (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)

#if ONION_PING_ID_SIZE != CRYPTO_PUBLIC_KEY_SIZE
Expand Down Expand Up @@ -57,7 +60,6 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data);


int create_gca_announce_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
Expand Down
70 changes: 70 additions & 0 deletions toxcore/onion_client.c
Expand Up @@ -990,6 +990,74 @@ static int handle_announce_response(void *object, IP_Port source, const uint8_t
return 0;
}

/* TODO: DEPRECATE */
static int handle_announce_response_leg(void *object, IP_Port source, const uint8_t *packet, uint16_t length,
void *userdata)
{
Onion_Client *onion_c = (Onion_Client *)object;

if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
return 1;
}

uint16_t len_nodes = length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;

uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
IP_Port ip_port;
uint32_t path_num;
uint32_t num = check_sendback(onion_c, packet + 1, public_key, &ip_port, &path_num);

if (num > onion_c->num_friends) {
return 1;
}

VLA(uint8_t, plain, 1 + ONION_PING_ID_SIZE + len_nodes);
int len;

if (num == 0) {
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
} else {
if (onion_c->friends_list[num - 1].status == 0) {
return 1;
}

len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
}

if ((uint32_t)len != SIZEOF_VLA(plain)) {
return 1;
}

uint32_t path_used = set_path_timeouts(onion_c, num, path_num);

if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, path_used) == -1) {
return 1;
}

if (len_nodes != 0) {
Node_format nodes[MAX_SENT_NODES];
int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, plain + 1 + ONION_PING_ID_SIZE, len_nodes, 0);

if (num_nodes <= 0) {
return 1;
}

if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
return 1;
}
}

// TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
return 0;
}

#define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE

static int handle_data_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
Expand Down Expand Up @@ -1985,6 +2053,7 @@ Onion_Client *new_onion_client(const Logger *logger, Mono_Time *mono_time, Net_C
new_symmetric_key(onion_c->secret_symmetric_key);
crypto_new_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_ANNOUNCE_RSPONSE_LEG, &handle_announce_response_leg, onion_c);
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c);
Expand All @@ -2002,6 +2071,7 @@ void kill_onion_client(Onion_Client *onion_c)
ping_array_kill(onion_c->announce_ping_array);
realloc_onion_friends(onion_c, 0);
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr);
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RSPONSE_LEG, nullptr, nullptr);
networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, nullptr, nullptr);
oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, nullptr, nullptr);
cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr);
Expand Down

0 comments on commit f3fef6a

Please sign in to comment.