summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-01-10 23:04:39 -0500
committerirungentoo <irungentoo@gmail.com>2014-01-10 23:04:39 -0500
commit94b5e55189800755d97bfe7953cc3773135036b0 (patch)
tree39da005a52009795bd62625131b2e22403f4fb72 /toxcore
parent91ce6092b41d33fe22bc33714b8df1f816d77724 (diff)
Some work on onion_client done.
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/onion_announce.h2
-rw-r--r--toxcore/onion_client.c129
-rw-r--r--toxcore/onion_client.h18
3 files changed, 135 insertions, 14 deletions
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index c314f55d..e51789e1 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -29,7 +29,7 @@
29#define ONION_ANNOUNCE_TIMEOUT 300 29#define ONION_ANNOUNCE_TIMEOUT 300
30#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES 30#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
31 31
32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + crypto_secretbox_MACBYTES) 32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + 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 + 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)
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index a1a038da..d2bdeedb 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -30,6 +30,10 @@
30#define ANNOUNCE_TIMEOUT 10 30#define ANNOUNCE_TIMEOUT 10
31 31
32/* Creates a sendback for use in an announce request. 32/* Creates a sendback for use in an announce request.
33 *
34 * num is 0 if we used our secret public key for the announce
35 * num is 1 + friendnum if we use a temporary one.
36 *
33 * Public key is the key we will be sending it to. 37 * Public key is the key we will be sending it to.
34 * 38 *
35 * sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big 39 * sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
@@ -38,12 +42,13 @@
38 * return 0 on success 42 * return 0 on success
39 * 43 *
40 */ 44 */
41static int new_sendback(Onion_Client *onion_c, uint8_t *public_key, uint8_t *sendback) 45static int new_sendback(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, uint8_t *sendback)
42{ 46{
43 uint8_t plain[sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES]; 47 uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES];
44 uint64_t time = unix_time(); 48 uint64_t time = unix_time();
45 memcpy(plain, &time, sizeof(uint64_t)); 49 memcpy(plain, &num, sizeof(uint32_t));
46 memcpy(plain + sizeof(uint64_t), public_key, crypto_box_PUBLICKEYBYTES); 50 memcpy(plain + sizeof(uint32_t), &time, sizeof(uint64_t));
51 memcpy(plain + sizeof(uint32_t) + sizeof(uint64_t), public_key, crypto_box_PUBLICKEYBYTES);
47 52
48 int len = encrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, plain, sizeof(plain), 53 int len = encrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, plain, sizeof(plain),
49 sendback + crypto_secretbox_NONCEBYTES); 54 sendback + crypto_secretbox_NONCEBYTES);
@@ -59,12 +64,12 @@ static int new_sendback(Onion_Client *onion_c, uint8_t *public_key, uint8_t *sen
59 * sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big 64 * sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
60 * returned_pubkey must be at least crypto_box_PUBLICKEYBYTES big 65 * returned_pubkey must be at least crypto_box_PUBLICKEYBYTES big
61 * 66 *
62 * return -1 on failure 67 * return ~0 on failure
63 * return 0 on success 68 * return num (see new_sendback(...)) on success
64 */ 69 */
65static int check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *returned_pubkey) 70static uint32_t check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *returned_pubkey)
66{ 71{
67 uint8_t plain[sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES]; 72 uint8_t plain[sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES];
68 int len = decrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, sendback + crypto_secretbox_NONCEBYTES, 73 int len = decrypt_data_symmetric(onion_c->secret_symmetric_key, sendback, sendback + crypto_secretbox_NONCEBYTES,
69 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH - crypto_secretbox_NONCEBYTES, plain); 74 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH - crypto_secretbox_NONCEBYTES, plain);
70 75
@@ -72,13 +77,88 @@ static int check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *ret
72 return -1; 77 return -1;
73 78
74 uint64_t timestamp; 79 uint64_t timestamp;
75 memcpy(&timestamp, plain, sizeof(uint64_t)); 80 memcpy(&timestamp, plain + sizeof(uint32_t), sizeof(uint64_t));
76 uint64_t temp_time = unix_time(); 81 uint64_t temp_time = unix_time();
77 82
78 if (timestamp + ANNOUNCE_TIMEOUT < temp_time || temp_time < timestamp) 83 if (timestamp + ANNOUNCE_TIMEOUT < temp_time || temp_time < timestamp)
79 return -1; 84 return -1;
80 85
81 memcpy(returned_pubkey, plain + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES); 86 memcpy(returned_pubkey, plain + sizeof(uint32_t) + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
87 uint32_t num;
88 memcpy(&num, plain, sizeof(uint32_t));
89 return plain[0];
90}
91
92static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, uint8_t *dest_pubkey,
93 uint8_t *ping_id)
94{
95 if (num > onion_c->num_friends)
96 return -1;
97
98 uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
99
100 if (new_sendback(onion_c, 0, dest_pubkey, sendback) == -1)
101 return -1;
102
103 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
104
105 if (ping_id == NULL)
106 ping_id = zero_ping_id;
107
108 Node_format nodes[4];
109
110 if (random_path(onion_c, nodes) == -1)
111 return -1;
112
113 nodes[3].ip_port = dest;
114 memcpy(nodes[3].client_id, dest_pubkey, crypto_box_PUBLICKEYBYTES);
115
116 if (num == 0) {
117 return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key,
118 onion_c->dht->c->self_secret_key, ping_id,
119 onion_c->dht->c->self_public_key, sendback);
120 } else {
121 return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key,
122 onion_c->friends_list[num - 1].temp_secret_key, ping_id,
123 onion_c->friends_list[num - 1].fake_client_id, sendback);
124 }
125}
126
127static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port,
128 uint8_t *ping_id)
129{
130
131 return 0;
132}
133
134static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *nodes, uint16_t num_nodes)
135{
136 if (num > onion_c->num_friends)
137 return -1;
138
139 if (num_nodes == 0)
140 return 0;
141
142 Onion_Node *list_nodes = NULL;
143 uint8_t *reference_id = NULL;
144
145 if (num == 0) {
146 list_nodes = onion_c->clients_announce_list;
147 reference_id = onion_c->dht->c->self_public_key;
148 } else {
149 list_nodes = onion_c->friends_list[num - 1].clients_list;
150 reference_id = onion_c->friends_list[num - 1].real_client_id;
151 }
152
153 uint32_t i;
154
155 for (i = 0; i < num_nodes; ++i) {
156 if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
157 || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) {
158 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL);
159 }
160 }
161
82 return 0; 162 return 0;
83} 163}
84 164
@@ -96,13 +176,38 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
96 176
97 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 177 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
98 178
99 if (check_sendback(onion_c, packet + 1, public_key) == -1) 179 uint32_t num = check_sendback(onion_c, packet + 1, public_key);
180
181 if (num > onion_c->num_friends)
100 return 1; 182 return 1;
101 183
102 uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; 184 uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)];
185 int len = -1;
186
187 if (num == 0) {
188 len = decrypt_data(public_key, onion_c->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
189 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES,
190 length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain);
191 } else {
192 if (onion_c->friends_list[num - 1].status == 0)
193 return 1;
194
195 len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
196 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
197 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES,
198 length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain);
199 }
200
201 if ((uint32_t)len != sizeof(plain))
202 return 1;
103 203
104 //int len = decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain);
105 //TODO 204 //TODO
205 //if (client_add_to_list(onion_c, num, uint8_t *public_key, IP_Port ip_port, plain) == -1)
206 // return 1;
207
208 if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes) == -1)
209 return 1;
210
106 return 0; 211 return 0;
107} 212}
108 213
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index a5f72e82..5becca48 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -27,7 +27,7 @@
27#include "onion_announce.h" 27#include "onion_announce.h"
28 28
29#define MAX_ONION_CLIENTS 8 29#define MAX_ONION_CLIENTS 8
30 30#define ONION_NODE_TIMEOUT 200
31typedef struct { 31typedef struct {
32 uint8_t client_id[CLIENT_ID_SIZE]; 32 uint8_t client_id[CLIENT_ID_SIZE];
33 IP_Port ip_port; 33 IP_Port ip_port;
@@ -36,7 +36,14 @@ typedef struct {
36} Onion_Node; 36} Onion_Node;
37 37
38typedef struct { 38typedef struct {
39 uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
40
41 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
42 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
43
39 Onion_Node clients_list[MAX_ONION_CLIENTS]; 44 Onion_Node clients_list[MAX_ONION_CLIENTS];
45 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
46 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
40} Onion_Friend; 47} Onion_Friend;
41 48
42typedef struct { 49typedef struct {
@@ -56,6 +63,15 @@ int onion_delfriend(Onion_Client *onion_c, uint8_t *client_id);
56 63
57int onion_getfriendip(Onion_Client *onion_c, uint8_t *client_id, IP_Port *ip_port); 64int onion_getfriendip(Onion_Client *onion_c, uint8_t *client_id, IP_Port *ip_port);
58 65
66/* Takes 3 random nodes that we know and puts them in nodes
67 *
68 * nodes must be longer than 3.
69 *
70 * return -1 on failure
71 * return 0 on success
72 *
73 */
74int random_path(Onion_Client *onion_c, Node_format *nodes);
59 75
60void do_onion_client(Onion_Client *onion_c); 76void do_onion_client(Onion_Client *onion_c);
61 77