diff options
author | irungentoo <irungentoo@gmail.com> | 2014-01-19 13:53:24 -0500 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-01-19 13:53:24 -0500 |
commit | 639b37de672b26daae6bdb4119c0eb677cde0b54 (patch) | |
tree | 229d0b8fec4e3519fca29d95012cd6e8f447650b /toxcore | |
parent | cdcb8b86007b6490557f1329f42c08732282c500 (diff) |
Small protocol change for more replay attack prevention.
see the changes to Prevent_Tracking.txt
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/onion_announce.c | 63 | ||||
-rw-r--r-- | toxcore/onion_announce.h | 16 | ||||
-rw-r--r-- | toxcore/onion_client.c | 35 | ||||
-rw-r--r-- | toxcore/onion_client.h | 5 |
4 files changed, 76 insertions, 43 deletions
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 3e4f7e0a..8150974b 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | #define PING_ID_TIMEOUT 20 | 30 | #define PING_ID_TIMEOUT 20 |
31 | 31 | ||
32 | #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) | 32 | #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) |
33 | #define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) | 33 | #define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) |
34 | 34 | ||
35 | #define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) | 35 | #define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) |
@@ -43,6 +43,7 @@ | |||
43 | * public_key and secret_key is the kepair which will be used to encrypt the request. | 43 | * public_key and secret_key is the kepair which will be used to encrypt the request. |
44 | * ping_id is the ping id that will be sent in the request. | 44 | * ping_id is the ping id that will be sent in the request. |
45 | * client_id is the client id of the node we are searching for. | 45 | * client_id is the client id of the node we are searching for. |
46 | * data_public_key is the public key we want others to encrypt their data packets with. | ||
46 | * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to | 47 | * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to |
47 | * receive back in the response. | 48 | * receive back in the response. |
48 | * | 49 | * |
@@ -50,12 +51,14 @@ | |||
50 | * return 0 on success. | 51 | * return 0 on success. |
51 | */ | 52 | */ |
52 | int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, | 53 | int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, |
53 | uint8_t *client_id, uint8_t *sendback_data) | 54 | uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data) |
54 | { | 55 | { |
55 | uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; | 56 | uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; |
56 | memcpy(plain, ping_id, ONION_PING_ID_SIZE); | 57 | memcpy(plain, ping_id, ONION_PING_ID_SIZE); |
57 | memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES); | 58 | memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES); |
58 | memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, sendback_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); | 59 | memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES); |
60 | memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, sendback_data, | ||
61 | ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); | ||
59 | uint8_t packet[ANNOUNCE_REQUEST_SIZE]; | 62 | uint8_t packet[ANNOUNCE_REQUEST_SIZE]; |
60 | packet[0] = NET_PACKET_ANNOUNCE_REQUEST; | 63 | packet[0] = NET_PACKET_ANNOUNCE_REQUEST; |
61 | new_nonce(packet + 1); | 64 | new_nonce(packet + 1); |
@@ -78,12 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin | |||
78 | * send the packet to that person in the form of a response) | 81 | * send the packet to that person in the form of a response) |
79 | * | 82 | * |
80 | * public_key is the real public key of the node which we want to send the data of length length to. | 83 | * public_key is the real public key of the node which we want to send the data of length length to. |
84 | * encrypt_public_key is the public key used to encrypt the data packet. | ||
85 | * | ||
81 | * nonce is the nonce to encrypt this packet with | 86 | * nonce is the nonce to encrypt this packet with |
82 | * | 87 | * |
83 | * return -1 on failure. | 88 | * return -1 on failure. |
84 | * return 0 on success. | 89 | * return 0 on success. |
85 | */ | 90 | */ |
86 | int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, uint16_t length) | 91 | int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce, |
92 | uint8_t *data, uint16_t length) | ||
87 | { | 93 | { |
88 | uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; | 94 | uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; |
89 | packet[0] = NET_PACKET_ONION_DATA_REQUEST; | 95 | packet[0] = NET_PACKET_ONION_DATA_REQUEST; |
@@ -96,7 +102,7 @@ int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t | |||
96 | 102 | ||
97 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); | 103 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); |
98 | 104 | ||
99 | int len = encrypt_data(public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, | 105 | int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, |
100 | data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); | 106 | data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); |
101 | 107 | ||
102 | if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) | 108 | if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) |
@@ -167,10 +173,11 @@ static int cmp_entry(const void *a, const void *b) | |||
167 | 173 | ||
168 | /* add entry to entries list | 174 | /* add entry to entries list |
169 | * | 175 | * |
170 | * return 0 if failure | 176 | * return -1 if failure |
171 | * return 1 if added | 177 | * return position if added |
172 | */ | 178 | */ |
173 | static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret) | 179 | static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *data_public_key, |
180 | uint8_t *ret) | ||
174 | { | 181 | { |
175 | 182 | ||
176 | int pos = in_entries(onion_a, public_key); | 183 | int pos = in_entries(onion_a, public_key); |
@@ -190,16 +197,17 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t | |||
190 | } | 197 | } |
191 | 198 | ||
192 | if (pos == -1) | 199 | if (pos == -1) |
193 | return 0; | 200 | return -1; |
194 | 201 | ||
195 | memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES); | 202 | memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES); |
196 | onion_a->entries[pos].ret_ip_port = ret_ip_port; | 203 | onion_a->entries[pos].ret_ip_port = ret_ip_port; |
197 | memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3); | 204 | memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3); |
205 | memcpy(onion_a->entries[pos].data_public_key, data_public_key, crypto_box_PUBLICKEYBYTES); | ||
198 | onion_a->entries[pos].time = unix_time(); | 206 | onion_a->entries[pos].time = unix_time(); |
199 | 207 | ||
200 | memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES); | 208 | memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES); |
201 | qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry); | 209 | qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry); |
202 | return 1; | 210 | return pos; |
203 | } | 211 | } |
204 | 212 | ||
205 | static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 213 | static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
@@ -209,10 +217,11 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet | |||
209 | if (length != ANNOUNCE_REQUEST_SIZE_RECV) | 217 | if (length != ANNOUNCE_REQUEST_SIZE_RECV) |
210 | return 1; | 218 | return 1; |
211 | 219 | ||
212 | uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; | 220 | uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; |
213 | int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1, | 221 | int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1, |
214 | packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 222 | packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
215 | ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES, plain); | 223 | ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + |
224 | crypto_box_MACBYTES, plain); | ||
216 | 225 | ||
217 | if ((uint32_t)len != sizeof(plain)) | 226 | if ((uint32_t)len != sizeof(plain)) |
218 | return 1; | 227 | return 1; |
@@ -223,13 +232,14 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet | |||
223 | uint8_t ping_id2[ONION_PING_ID_SIZE]; | 232 | uint8_t ping_id2[ONION_PING_ID_SIZE]; |
224 | generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2); | 233 | generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2); |
225 | 234 | ||
226 | int stored = 0; | 235 | int index = -1; |
227 | 236 | ||
228 | if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { | 237 | if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { |
229 | stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES, | 238 | index = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES, |
230 | packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)); | 239 | plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, |
240 | packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)); | ||
231 | } else { | 241 | } else { |
232 | stored = (in_entries(onion_a, plain + ONION_PING_ID_SIZE) != -1); | 242 | index = in_entries(onion_a, plain + ONION_PING_ID_SIZE); |
233 | } | 243 | } |
234 | 244 | ||
235 | /*Respond with a announce response packet*/ | 245 | /*Respond with a announce response packet*/ |
@@ -245,24 +255,29 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet | |||
245 | uint8_t nonce[crypto_box_NONCEBYTES]; | 255 | uint8_t nonce[crypto_box_NONCEBYTES]; |
246 | new_nonce(nonce); | 256 | new_nonce(nonce); |
247 | 257 | ||
248 | uint8_t pl[ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0}; | 258 | uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)]; |
249 | 259 | ||
250 | if (!stored) { | 260 | if (index == -1) { |
251 | memcpy(pl, ping_id2, ONION_PING_ID_SIZE); | 261 | pl[0] = 0; |
262 | memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE); | ||
263 | } else { | ||
264 | pl[0] = 1; | ||
265 | memcpy(pl + 1, onion_a->entries[index].data_public_key, crypto_box_PUBLICKEYBYTES); | ||
252 | } | 266 | } |
253 | 267 | ||
254 | memcpy(pl + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); | 268 | memcpy(pl + 1 + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); |
255 | 269 | ||
256 | uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; | 270 | uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; |
257 | len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, | 271 | len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, |
258 | ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), | 272 | 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), |
259 | data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); | 273 | data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); |
260 | 274 | ||
261 | if ((uint32_t)len != ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) | 275 | if ((uint32_t)len != 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) |
262 | return 1; | 276 | return 1; |
263 | 277 | ||
264 | data[0] = NET_PACKET_ANNOUNCE_RESPONSE; | 278 | data[0] = NET_PACKET_ANNOUNCE_RESPONSE; |
265 | memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); | 279 | memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, |
280 | ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); | ||
266 | memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES); | 281 | memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES); |
267 | 282 | ||
268 | if (send_onion_response(onion_a->net, source, data, | 283 | if (send_onion_response(onion_a->net, source, data, |
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 01cd7243..27b25bd4 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h | |||
@@ -31,15 +31,20 @@ | |||
31 | 31 | ||
32 | #define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES) | 32 | #define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES) |
33 | 33 | ||
34 | #define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + crypto_box_MACBYTES) | 34 | #define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + 1 + ONION_PING_ID_SIZE + crypto_box_MACBYTES) |
35 | #define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) | 35 | #define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) |
36 | 36 | ||
37 | #define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) | 37 | #define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) |
38 | 38 | ||
39 | #if ONION_PING_ID_SIZE != crypto_box_PUBLICKEYBYTES | ||
40 | #error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES | ||
41 | #endif | ||
42 | |||
39 | typedef struct { | 43 | typedef struct { |
40 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 44 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
41 | IP_Port ret_ip_port; | 45 | IP_Port ret_ip_port; |
42 | uint8_t ret[ONION_RETURN_3]; | 46 | uint8_t ret[ONION_RETURN_3]; |
47 | uint8_t data_public_key[crypto_box_PUBLICKEYBYTES]; | ||
43 | uint64_t time; | 48 | uint64_t time; |
44 | } Onion_Announce_Entry; | 49 | } Onion_Announce_Entry; |
45 | 50 | ||
@@ -59,6 +64,7 @@ typedef struct { | |||
59 | * public_key and secret_key is the kepair which will be used to encrypt the request. | 64 | * public_key and secret_key is the kepair which will be used to encrypt the request. |
60 | * ping_id is the ping id that will be sent in the request. | 65 | * ping_id is the ping id that will be sent in the request. |
61 | * client_id is the client id of the node we are searching for. | 66 | * client_id is the client id of the node we are searching for. |
67 | * data_public_key is the public key we want others to encrypt their data packets with. | ||
62 | * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to | 68 | * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to |
63 | * receive back in the response. | 69 | * receive back in the response. |
64 | * | 70 | * |
@@ -66,7 +72,7 @@ typedef struct { | |||
66 | * return 0 on success. | 72 | * return 0 on success. |
67 | */ | 73 | */ |
68 | int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, | 74 | int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, |
69 | uint8_t *client_id, uint8_t *sendback_data); | 75 | uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data); |
70 | 76 | ||
71 | /* Create and send an onion data request packet. | 77 | /* Create and send an onion data request packet. |
72 | * | 78 | * |
@@ -75,13 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin | |||
75 | * send the packet to that person in the form of a response) | 81 | * send the packet to that person in the form of a response) |
76 | * | 82 | * |
77 | * public_key is the real public key of the node which we want to send the data of length length to. | 83 | * public_key is the real public key of the node which we want to send the data of length length to. |
84 | * encrypt_public_key is the public key used to encrypt the data packet. | ||
85 | * | ||
78 | * nonce is the nonce to encrypt this packet with | 86 | * nonce is the nonce to encrypt this packet with |
79 | * | 87 | * |
80 | * return -1 on failure. | 88 | * return -1 on failure. |
81 | * return 0 on success. | 89 | * return 0 on success. |
82 | */ | 90 | */ |
83 | int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, | 91 | int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce, |
84 | uint16_t length); | 92 | uint8_t *data, uint16_t length); |
85 | 93 | ||
86 | 94 | ||
87 | Onion_Announce *new_onion_announce(DHT *dht); | 95 | Onion_Announce *new_onion_announce(DHT *dht); |
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index e50679e5..06f64929 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | #define ANNOUNCE_TIMEOUT 10 | 31 | #define ANNOUNCE_TIMEOUT 10 |
32 | 32 | ||
33 | static uint8_t zero_ping[ONION_PING_ID_SIZE]; | ||
34 | 33 | ||
35 | /* Creates a sendback for use in an announce request. | 34 | /* Creates a sendback for use in an announce request. |
36 | * | 35 | * |
@@ -126,11 +125,11 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_ | |||
126 | if (num == 0) { | 125 | if (num == 0) { |
127 | return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key, | 126 | return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key, |
128 | onion_c->dht->c->self_secret_key, ping_id, | 127 | onion_c->dht->c->self_secret_key, ping_id, |
129 | onion_c->dht->c->self_public_key, sendback); | 128 | onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback); |
130 | } else { | 129 | } else { |
131 | return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key, | 130 | return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key, |
132 | onion_c->friends_list[num - 1].temp_secret_key, ping_id, | 131 | onion_c->friends_list[num - 1].temp_secret_key, ping_id, |
133 | onion_c->friends_list[num - 1].real_client_id, sendback); | 132 | onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback); |
134 | } | 133 | } |
135 | } | 134 | } |
136 | 135 | ||
@@ -164,7 +163,7 @@ static int cmp_entry(const void *a, const void *b) | |||
164 | } | 163 | } |
165 | 164 | ||
166 | static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, | 165 | static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, |
167 | uint8_t *ping_id) | 166 | uint8_t is_stored, uint8_t *pingid_or_key) |
168 | { | 167 | { |
169 | if (num > onion_c->num_friends) | 168 | if (num > onion_c->num_friends) |
170 | return -1; | 169 | return -1; |
@@ -204,7 +203,14 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ | |||
204 | 203 | ||
205 | memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE); | 204 | memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE); |
206 | list_nodes[index].ip_port = ip_port; | 205 | list_nodes[index].ip_port = ip_port; |
207 | memcpy(list_nodes[index].ping_id, ping_id, ONION_PING_ID_SIZE); | 206 | |
207 | if (is_stored) { | ||
208 | memcpy(list_nodes[index].data_public_key, pingid_or_key, crypto_box_PUBLICKEYBYTES); | ||
209 | } else { | ||
210 | memcpy(list_nodes[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE); | ||
211 | } | ||
212 | |||
213 | list_nodes[index].is_stored = is_stored; | ||
208 | list_nodes[index].timestamp = unix_time(); | 214 | list_nodes[index].timestamp = unix_time(); |
209 | list_nodes[index].last_pinged = 0; | 215 | list_nodes[index].last_pinged = 0; |
210 | return 0; | 216 | return 0; |
@@ -276,7 +282,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe | |||
276 | if (num > onion_c->num_friends) | 282 | if (num > onion_c->num_friends) |
277 | return 1; | 283 | return 1; |
278 | 284 | ||
279 | uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; | 285 | uint8_t plain[1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; |
280 | int len = -1; | 286 | int len = -1; |
281 | 287 | ||
282 | if (num == 0) { | 288 | if (num == 0) { |
@@ -297,10 +303,10 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe | |||
297 | return 1; | 303 | return 1; |
298 | 304 | ||
299 | 305 | ||
300 | if (client_add_to_list(onion_c, num, public_key, ip_port, plain) == -1) | 306 | if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1) == -1) |
301 | return 1; | 307 | return 1; |
302 | 308 | ||
303 | if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes, source) == -1) | 309 | if (client_ping_nodes(onion_c, num, (Node_format *)plain + 1 + ONION_PING_ID_SIZE, num_nodes, source) == -1) |
304 | return 1; | 310 | return 1; |
305 | 311 | ||
306 | return 0; | 312 | return 0; |
@@ -319,7 +325,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u | |||
319 | return 1; | 325 | return 1; |
320 | 326 | ||
321 | uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE]; | 327 | uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE]; |
322 | int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->dht->c->self_secret_key, packet + 1, | 328 | int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->temp_secret_key, packet + 1, |
323 | packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, | 329 | packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, |
324 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain); | 330 | length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain); |
325 | 331 | ||
@@ -391,7 +397,6 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t | |||
391 | DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); | 397 | DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); |
392 | } | 398 | } |
393 | 399 | ||
394 | //TODO replay protection | ||
395 | return 0; | 400 | return 0; |
396 | } | 401 | } |
397 | /* Send data of length length to friendnum. | 402 | /* Send data of length length to friendnum. |
@@ -431,7 +436,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32 | |||
431 | if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) | 436 | if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) |
432 | continue; | 437 | continue; |
433 | 438 | ||
434 | if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { | 439 | if (list_nodes[i].is_stored) { |
435 | Node_format nodes[4]; | 440 | Node_format nodes[4]; |
436 | 441 | ||
437 | if (random_path(onion_c, nodes) == -1) | 442 | if (random_path(onion_c, nodes) == -1) |
@@ -440,8 +445,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32 | |||
440 | memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES); | 445 | memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES); |
441 | nodes[3].ip_port = list_nodes[i].ip_port; | 446 | nodes[3].ip_port = list_nodes[i].ip_port; |
442 | 447 | ||
443 | if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id, nonce, packet, | 448 | if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id, |
444 | sizeof(packet)) == 0) | 449 | list_nodes[i].data_public_key, nonce, packet, sizeof(packet)) == 0) |
445 | ++good; | 450 | ++good; |
446 | } | 451 | } |
447 | } | 452 | } |
@@ -697,7 +702,7 @@ static void do_announce(Onion_Client *onion_c) | |||
697 | ++count; | 702 | ++count; |
698 | uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; | 703 | uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; |
699 | 704 | ||
700 | if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { | 705 | if (list_nodes[i].is_stored) { |
701 | interval = ANNOUNCE_INTERVAL_ANNOUNCED; | 706 | interval = ANNOUNCE_INTERVAL_ANNOUNCED; |
702 | } | 707 | } |
703 | 708 | ||
@@ -748,7 +753,7 @@ Onion_Client *new_onion_client(DHT *dht) | |||
748 | onion_c->dht = dht; | 753 | onion_c->dht = dht; |
749 | onion_c->net = dht->c->lossless_udp->net; | 754 | onion_c->net = dht->c->lossless_udp->net; |
750 | new_symmetric_key(onion_c->secret_symmetric_key); | 755 | new_symmetric_key(onion_c->secret_symmetric_key); |
751 | 756 | crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key); | |
752 | networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); | 757 | networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); |
753 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); | 758 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); |
754 | oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); | 759 | oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); |
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 56adc9ee..afc29f77 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h | |||
@@ -36,6 +36,9 @@ typedef struct { | |||
36 | uint8_t client_id[CLIENT_ID_SIZE]; | 36 | uint8_t client_id[CLIENT_ID_SIZE]; |
37 | IP_Port ip_port; | 37 | IP_Port ip_port; |
38 | uint8_t ping_id[ONION_PING_ID_SIZE]; | 38 | uint8_t ping_id[ONION_PING_ID_SIZE]; |
39 | uint8_t data_public_key[crypto_box_PUBLICKEYBYTES]; | ||
40 | uint8_t is_stored; | ||
41 | |||
39 | uint64_t timestamp; | 42 | uint64_t timestamp; |
40 | 43 | ||
41 | uint64_t last_pinged; | 44 | uint64_t last_pinged; |
@@ -70,6 +73,8 @@ typedef struct { | |||
70 | uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; | 73 | uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; |
71 | uint64_t last_run; | 74 | uint64_t last_run; |
72 | 75 | ||
76 | uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; | ||
77 | uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; | ||
73 | struct { | 78 | struct { |
74 | oniondata_handler_callback function; | 79 | oniondata_handler_callback function; |
75 | void *object; | 80 | void *object; |