mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Fixed problem in onion_announce.c
Added a way to know if a announce response is valid.
This commit is contained in:
parent
5e6e503201
commit
0fd8e49c38
|
@ -65,6 +65,7 @@ void print_client_id(uint8_t *client_id, uint32_t length)
|
|||
printf("\n");
|
||||
}
|
||||
*/
|
||||
uint8_t sb_data[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
static int handled_test_3;
|
||||
uint8_t test_3_pub_key[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t test_3_ping_id[crypto_hash_sha256_BYTES];
|
||||
|
@ -72,16 +73,22 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t
|
|||
{
|
||||
Onion *onion = object;
|
||||
|
||||
if (length != (1 + crypto_box_NONCEBYTES + crypto_hash_sha256_BYTES + crypto_box_MACBYTES))
|
||||
if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_hash_sha256_BYTES +
|
||||
crypto_box_MACBYTES))
|
||||
return 1;
|
||||
|
||||
uint8_t plain[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_hash_sha256_BYTES];
|
||||
//print_client_id(packet, length);
|
||||
int len = decrypt_data(test_3_pub_key, onion->dht->c->self_secret_key, packet + 1, packet + 1 + crypto_box_NONCEBYTES,
|
||||
crypto_hash_sha256_BYTES + crypto_box_MACBYTES, test_3_ping_id);
|
||||
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain);
|
||||
|
||||
if (len == -1)
|
||||
return 1;
|
||||
|
||||
if (memcmp(plain, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0)
|
||||
return 1;
|
||||
|
||||
memcpy(test_3_ping_id, plain + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, crypto_hash_sha256_BYTES);
|
||||
//print_client_id(test_3_ping_id, sizeof(test_3_ping_id));
|
||||
handled_test_3 = 1;
|
||||
return 0;
|
||||
|
@ -157,9 +164,10 @@ START_TEST(test_basic)
|
|||
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1);
|
||||
ck_assert_msg((onion1_a != NULL) && (onion2_a != NULL), "Onion_Announce failed initializing.");
|
||||
uint8_t zeroes[64] = {0};
|
||||
randombytes(sb_data, sizeof(sb_data));
|
||||
memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES);
|
||||
ret = send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key,
|
||||
zeroes, onion1->dht->c->self_public_key);
|
||||
zeroes, onion1->dht->c->self_public_key, sb_data);
|
||||
ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet.");
|
||||
handled_test_3 = 0;
|
||||
|
||||
|
@ -168,11 +176,12 @@ START_TEST(test_basic)
|
|||
do_onion(onion2);
|
||||
}
|
||||
|
||||
randombytes(sb_data, sizeof(sb_data));
|
||||
memcpy(onion2_a->entries[1].public_key, onion2->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
|
||||
onion2_a->entries[1].time = unix_time();
|
||||
networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
|
||||
send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key,
|
||||
test_3_ping_id, onion1->dht->c->self_public_key);
|
||||
test_3_ping_id, onion1->dht->c->self_public_key, sb_data);
|
||||
|
||||
while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key,
|
||||
crypto_box_PUBLICKEYBYTES) != 0) {
|
||||
|
|
|
@ -97,7 +97,7 @@ Data sent to Node D:
|
|||
|
||||
announce request packet:
|
||||
[uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)]
|
||||
encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:[[(32 bytes) ping_id][client id we are searching for]]
|
||||
encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:[[(32 bytes) ping_id][client id we are searching for][data to send back in response(fixed size)]]
|
||||
|
||||
(if the ping id is zero, respond with a announce response packet)
|
||||
(If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for,
|
||||
|
@ -111,7 +111,7 @@ encrypted with that temporary private key and the nonce and the real public key
|
|||
Data sent to us:
|
||||
announce response packet:
|
||||
[uint8_t packet id (132)][nonce]
|
||||
encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[(32 bytes) ping_id][Node_Format * (maximum of 8)]]
|
||||
encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[data to send back in response(fixed size)][(32 bytes) ping_id][Node_Format * (maximum of 8)]]
|
||||
(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node)
|
||||
|
||||
data to route response packet:
|
||||
|
|
|
@ -27,12 +27,11 @@
|
|||
#include "LAN_discovery.h"
|
||||
#include "util.h"
|
||||
|
||||
#define PING_ID_SIZE crypto_hash_sha256_BYTES
|
||||
#define PING_ID_TIMEOUT 10
|
||||
|
||||
#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
|
||||
#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
|
||||
#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + PING_ID_SIZE + crypto_box_MACBYTES)
|
||||
#define ANNOUNCE_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
|
||||
#define ANNOUNCE_RESPONSE_MAX_SIZE (ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
|
||||
|
||||
#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
|
||||
|
@ -46,17 +45,19 @@
|
|||
* public_key and secret_key is the kepair which will be used to encrypt the request.
|
||||
* ping_id is the ping id that will be sent in the request.
|
||||
* client_id is the client id of the node we are searching for.
|
||||
* sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
|
||||
* receive back in the response.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id,
|
||||
uint8_t *client_id)
|
||||
uint8_t *client_id, uint8_t *sendback_data)
|
||||
{
|
||||
uint8_t plain[PING_ID_SIZE + crypto_box_PUBLICKEYBYTES];
|
||||
memcpy(plain, ping_id, PING_ID_SIZE);
|
||||
memcpy(plain + PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
|
||||
|
||||
uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
memcpy(plain, ping_id, ONION_PING_ID_SIZE);
|
||||
memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
|
||||
memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, sendback_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||
uint8_t packet[ANNOUNCE_REQUEST_SIZE];
|
||||
packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
|
||||
new_nonce(packet + 1);
|
||||
|
@ -210,50 +211,54 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
|
|||
if (length != ANNOUNCE_REQUEST_SIZE_RECV)
|
||||
return 1;
|
||||
|
||||
uint8_t plain[PING_ID_SIZE + crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
|
||||
int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1,
|
||||
packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
|
||||
PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES, plain);
|
||||
ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES, plain);
|
||||
|
||||
if ((uint32_t)len != sizeof(plain))
|
||||
return 1;
|
||||
|
||||
uint8_t ping_id1[PING_ID_SIZE];
|
||||
uint8_t ping_id1[ONION_PING_ID_SIZE];
|
||||
generate_ping_id(onion_a, unix_time(), packet + 1 + crypto_box_NONCEBYTES, source, ping_id1);
|
||||
|
||||
uint8_t ping_id2[PING_ID_SIZE];
|
||||
uint8_t ping_id2[ONION_PING_ID_SIZE];
|
||||
generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2);
|
||||
|
||||
int stored = 0;
|
||||
|
||||
if (memcmp(ping_id1, plain, PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, PING_ID_SIZE) == 0) {
|
||||
if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
|
||||
stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
|
||||
packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
|
||||
} else {
|
||||
stored = (in_entries(onion_a, plain + PING_ID_SIZE) != -1);
|
||||
stored = (in_entries(onion_a, plain + ONION_PING_ID_SIZE) != -1);
|
||||
}
|
||||
|
||||
/*Respond with a announce response packet*/
|
||||
Node_format nodes_list[MAX_SENT_NODES];
|
||||
uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + PING_ID_SIZE, nodes_list, source.ip.family,
|
||||
uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, source.ip.family,
|
||||
LAN_ip(source.ip) == 0, 1);
|
||||
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
new_nonce(nonce);
|
||||
|
||||
uint8_t pl[PING_ID_SIZE + sizeof(nodes_list)] = {0};
|
||||
uint8_t pl[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0};
|
||||
|
||||
memcpy(pl, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
|
||||
|
||||
if (!stored) {
|
||||
memcpy(pl, ping_id2, PING_ID_SIZE);
|
||||
memcpy(pl + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, ping_id2, ONION_PING_ID_SIZE);
|
||||
}
|
||||
|
||||
memcpy(pl + PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format));
|
||||
memcpy(pl + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format));
|
||||
|
||||
uint8_t data[ANNOUNCE_RESPONSE_MAX_SIZE];
|
||||
len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl,
|
||||
PING_ID_SIZE + num_nodes * sizeof(Node_format), data + 1 + crypto_box_NONCEBYTES);
|
||||
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format),
|
||||
data + 1 + crypto_box_NONCEBYTES);
|
||||
|
||||
if ((uint32_t)len != PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES)
|
||||
if ((uint32_t)len != ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + ONION_PING_ID_SIZE + num_nodes * sizeof(
|
||||
Node_format) + crypto_box_MACBYTES)
|
||||
return 1;
|
||||
|
||||
data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#define ONION_ANNOUNCE_MAX_ENTRIES 32
|
||||
#define ONION_ANNOUNCE_TIMEOUT 300
|
||||
#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
|
||||
|
||||
#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + crypto_secretbox_MACBYTES)
|
||||
|
||||
typedef struct {
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
|
@ -51,12 +54,14 @@ typedef struct {
|
|||
* public_key and secret_key is the kepair which will be used to encrypt the request.
|
||||
* ping_id is the ping id that will be sent in the request.
|
||||
* client_id is the client id of the node we are searching for.
|
||||
* sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
|
||||
* receive back in the response.
|
||||
*
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id,
|
||||
uint8_t *client_id);
|
||||
uint8_t *client_id, uint8_t *sendback_data);
|
||||
|
||||
/* Create and send an onion data request packet.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue
Block a user