diff options
author | irungentoo <irungentoo@gmail.com> | 2014-01-10 23:04:39 -0500 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-01-10 23:04:39 -0500 |
commit | 94b5e55189800755d97bfe7953cc3773135036b0 (patch) | |
tree | 39da005a52009795bd62625131b2e22403f4fb72 /toxcore | |
parent | 91ce6092b41d33fe22bc33714b8df1f816d77724 (diff) |
Some work on onion_client done.
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/onion_announce.h | 2 | ||||
-rw-r--r-- | toxcore/onion_client.c | 129 | ||||
-rw-r--r-- | toxcore/onion_client.h | 18 |
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 | */ |
41 | static int new_sendback(Onion_Client *onion_c, uint8_t *public_key, uint8_t *sendback) | 45 | static 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 | */ |
65 | static int check_sendback(Onion_Client *onion_c, uint8_t *sendback, uint8_t *returned_pubkey) | 70 | static 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(×tamp, plain, sizeof(uint64_t)); | 80 | memcpy(×tamp, 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 | |||
92 | static 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 | |||
127 | static 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 | |||
134 | static 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 | |
31 | typedef struct { | 31 | typedef 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 | ||
38 | typedef struct { | 38 | typedef 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 | ||
42 | typedef struct { | 49 | typedef struct { |
@@ -56,6 +63,15 @@ int onion_delfriend(Onion_Client *onion_c, uint8_t *client_id); | |||
56 | 63 | ||
57 | int onion_getfriendip(Onion_Client *onion_c, uint8_t *client_id, IP_Port *ip_port); | 64 | int 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 | */ | ||
74 | int random_path(Onion_Client *onion_c, Node_format *nodes); | ||
59 | 75 | ||
60 | void do_onion_client(Onion_Client *onion_c); | 76 | void do_onion_client(Onion_Client *onion_c); |
61 | 77 | ||