summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-01-19 13:53:24 -0500
committerirungentoo <irungentoo@gmail.com>2014-01-19 13:53:24 -0500
commit639b37de672b26daae6bdb4119c0eb677cde0b54 (patch)
tree229d0b8fec4e3519fca29d95012cd6e8f447650b /toxcore
parentcdcb8b86007b6490557f1329f42c08732282c500 (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.c63
-rw-r--r--toxcore/onion_announce.h16
-rw-r--r--toxcore/onion_client.c35
-rw-r--r--toxcore/onion_client.h5
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 */
52int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, 53int 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 */
86int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, uint16_t length) 91int 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 */
173static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret) 179static 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
205static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) 213static 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
39typedef struct { 43typedef 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 */
68int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, 74int 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 */
83int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, 91int 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
87Onion_Announce *new_onion_announce(DHT *dht); 95Onion_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
33static 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
166static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, 165static 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;