summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/TCP_test.c162
-rw-r--r--toxcore/TCP_server.c61
-rw-r--r--toxcore/TCP_server.h5
3 files changed, 218 insertions, 10 deletions
diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c
index 983b07d2..989867b4 100644
--- a/auto_tests/TCP_test.c
+++ b/auto_tests/TCP_test.c
@@ -21,9 +21,10 @@
21 21
22#define NUM_PORTS 3 22#define NUM_PORTS 3
23 23
24uint16_t ports[NUM_PORTS] = {12345, 33445, 25643};
25
24START_TEST(test_basic) 26START_TEST(test_basic)
25{ 27{
26 uint16_t ports[NUM_PORTS] = {12345, 33445, 25643};
27 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 28 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
28 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; 29 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
29 crypto_box_keypair(self_public_key, self_secret_key); 30 crypto_box_keypair(self_public_key, self_secret_key);
@@ -80,7 +81,165 @@ START_TEST(test_basic)
80 encrypt_precompute(response_plain, t_secret_key, f_shared_key); 81 encrypt_precompute(response_plain, t_secret_key, f_shared_key);
81 memcpy(f_nonce_r, response_plain + crypto_box_BEFORENMBYTES, crypto_box_NONCEBYTES); 82 memcpy(f_nonce_r, response_plain + crypto_box_BEFORENMBYTES, crypto_box_NONCEBYTES);
82 83
84 uint8_t r_req_p[1 + crypto_box_PUBLICKEYBYTES] = {0};
85 memcpy(r_req_p + 1, f_public_key, crypto_box_PUBLICKEYBYTES);
86 uint8_t r_req[2 + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES];
87 uint16_t size = 1 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES;
88 size = htons(size);
89 ret = encrypt_data_fast(f_shared_key, f_nonce, r_req_p, 1 + crypto_box_PUBLICKEYBYTES, r_req + 2);
90 increment_nonce(f_nonce);
91 memcpy(r_req, &size, 2);
92 uint32_t i;
93
94 for (i = 0; i < sizeof(r_req); ++i) {
95 ck_assert_msg(send(sock, r_req + i, 1, 0) == 1, "send Failed.");
96 //ck_assert_msg(send(sock, r_req, sizeof(r_req), 0) == sizeof(r_req), "send Failed.");
97 do_TCP_server(tcp_s);
98 c_sleep(50);
99 }
83 100
101 do_TCP_server(tcp_s);
102 c_sleep(50);
103 uint8_t packet_resp[4096];
104 int recv_data_len;
105 ck_assert_msg((recv_data_len = recv(sock, packet_resp, 2 + 2 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES,
106 0)) == 2 + 2 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES, "recv Failed. %u", recv_data_len);
107 memcpy(&size, packet_resp, 2);
108 ck_assert_msg(ntohs(size) == 2 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES, "Wrong packet size.");
109 uint8_t packet_resp_plain[4096];
110 ret = decrypt_data_fast(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain);
111 ck_assert_msg(ret != -1, "decryption failed");
112 increment_nonce(f_nonce_r);
113 ck_assert_msg(packet_resp_plain[0] == 1, "wrong packet id %u", packet_resp_plain[0]);
114 ck_assert_msg(packet_resp_plain[1] == 0, "connection not refused %u", packet_resp_plain[1]);
115 ck_assert_msg(memcmp(packet_resp_plain + 2, f_public_key, crypto_box_PUBLICKEYBYTES) == 0, "key in packet wrong");
116}
117END_TEST
118
119struct sec_TCP_con {
120 sock_t sock;
121 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
122 uint8_t recv_nonce[crypto_box_NONCEBYTES];
123 uint8_t sent_nonce[crypto_box_NONCEBYTES];
124 uint8_t shared_key[crypto_box_BEFORENMBYTES];
125};
126
127struct sec_TCP_con *new_TCP_con(TCP_Server *tcp_s)
128{
129 struct sec_TCP_con *sec_c = malloc(sizeof(struct sec_TCP_con));
130 sock_t sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
131 struct sockaddr_in6 addr6_loopback = {0};
132 addr6_loopback.sin6_family = AF_INET6;
133 addr6_loopback.sin6_port = htons(ports[rand() % NUM_PORTS]);
134 addr6_loopback.sin6_addr = in6addr_loopback;
135
136 int ret = connect(sock, (struct sockaddr *)&addr6_loopback, sizeof(addr6_loopback));
137 ck_assert_msg(ret == 0, "Failed to connect to TCP relay server");
138
139 uint8_t f_secret_key[crypto_box_SECRETKEYBYTES];
140 crypto_box_keypair(sec_c->public_key, f_secret_key);
141 random_nonce(sec_c->sent_nonce);
142
143 uint8_t t_secret_key[crypto_box_SECRETKEYBYTES];
144 uint8_t handshake_plain[TCP_HANDSHAKE_PLAIN_SIZE];
145 crypto_box_keypair(handshake_plain, t_secret_key);
146 memcpy(handshake_plain + crypto_box_PUBLICKEYBYTES, sec_c->sent_nonce, crypto_box_NONCEBYTES);
147 uint8_t handshake[TCP_CLIENT_HANDSHAKE_SIZE];
148 memcpy(handshake, sec_c->public_key, crypto_box_PUBLICKEYBYTES);
149 new_nonce(handshake + crypto_box_PUBLICKEYBYTES);
150
151 ret = encrypt_data(tcp_s->public_key, f_secret_key, handshake + crypto_box_PUBLICKEYBYTES, handshake_plain,
152 TCP_HANDSHAKE_PLAIN_SIZE, handshake + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
153 ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES),
154 "Encrypt failed.");
155 ck_assert_msg(send(sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1, 0) == TCP_CLIENT_HANDSHAKE_SIZE - 1, "send Failed.");
156 do_TCP_server(tcp_s);
157 c_sleep(50);
158 ck_assert_msg(send(sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, 0) == 1, "send Failed.");
159 c_sleep(50);
160 do_TCP_server(tcp_s);
161 uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
162 uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE];
163 ck_assert_msg(recv(sock, response, TCP_SERVER_HANDSHAKE_SIZE, 0) == TCP_SERVER_HANDSHAKE_SIZE, "recv Failed.");
164 ret = decrypt_data(tcp_s->public_key, f_secret_key, response, response + crypto_box_NONCEBYTES,
165 TCP_SERVER_HANDSHAKE_SIZE - crypto_box_NONCEBYTES, response_plain);
166 ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Decrypt Failed.");
167 encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key);
168 memcpy(sec_c->recv_nonce, response_plain + crypto_box_BEFORENMBYTES, crypto_box_NONCEBYTES);
169 sec_c->sock = sock;
170 return sec_c;
171}
172
173int write_packet_TCP_secure_connection(struct sec_TCP_con *con, uint8_t *data, uint16_t length)
174{
175 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
176
177 uint16_t c_length = htons(length + crypto_box_MACBYTES);
178 memcpy(packet, &c_length, sizeof(uint16_t));
179 int len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
180
181 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
182 return -1;
183
184 increment_nonce(con->sent_nonce);
185
186 ck_assert_msg(send(con->sock, packet, sizeof(packet), 0) == sizeof(packet), "send failed");
187 return 0;
188}
189
190int read_packet_sec_TCP(struct sec_TCP_con *con, uint8_t *data, uint16_t length)
191{
192 int len;
193 ck_assert_msg((len = recv(con->sock, data, length, 0)) == length, "wrong len %i\n", len);
194 ck_assert_msg((len = decrypt_data_fast(con->shared_key, con->recv_nonce, data + 2, length - 2, data)) != -1,
195 "Decrypt failed");
196 increment_nonce(con->recv_nonce);
197 return len;
198}
199
200START_TEST(test_some)
201{
202 uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
203 uint8_t self_secret_key[crypto_box_SECRETKEYBYTES];
204 crypto_box_keypair(self_public_key, self_secret_key);
205 TCP_Server *tcp_s = new_TCP_server(1, NUM_PORTS, ports, self_public_key, self_secret_key);
206 ck_assert_msg(tcp_s != NULL, "Failed to create TCP relay server");
207
208 struct sec_TCP_con *con1 = new_TCP_con(tcp_s);
209 struct sec_TCP_con *con2 = new_TCP_con(tcp_s);
210 struct sec_TCP_con *con3 = new_TCP_con(tcp_s);
211
212 uint8_t requ_p[1 + crypto_box_PUBLICKEYBYTES];
213 requ_p[0] = 0;
214 memcpy(requ_p + 1, con3->public_key, crypto_box_PUBLICKEYBYTES);
215 write_packet_TCP_secure_connection(con1, requ_p, sizeof(requ_p));
216 memcpy(requ_p + 1, con1->public_key, crypto_box_PUBLICKEYBYTES);
217 write_packet_TCP_secure_connection(con3, requ_p, sizeof(requ_p));
218 do_TCP_server(tcp_s);
219 c_sleep(50);
220 uint8_t data[2048];
221 int len = read_packet_sec_TCP(con1, data, 2 + 1 + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES);
222 ck_assert_msg(len == 1 + 1 + crypto_box_PUBLICKEYBYTES, "wrong len %u", len);
223 ck_assert_msg(data[0] == 1, "wrong packet id %u", data[0]);
224 ck_assert_msg(data[1] == 16, "connection not refused %u", data[1]);
225 ck_assert_msg(memcmp(data + 2, con3->public_key, crypto_box_PUBLICKEYBYTES) == 0, "key in packet wrong");
226 len = read_packet_sec_TCP(con3, data, 2 + 1 + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES);
227 ck_assert_msg(len == 1 + 1 + crypto_box_PUBLICKEYBYTES, "wrong len %u", len);
228 ck_assert_msg(data[0] == 1, "wrong packet id %u", data[0]);
229 ck_assert_msg(data[1] == 16, "connection not refused %u", data[1]);
230 ck_assert_msg(memcmp(data + 2, con1->public_key, crypto_box_PUBLICKEYBYTES) == 0, "key in packet wrong");
231
232 uint8_t test_packet[1024] = {16};
233 write_packet_TCP_secure_connection(con3, test_packet, sizeof(test_packet));
234 do_TCP_server(tcp_s);
235 c_sleep(50);
236 len = read_packet_sec_TCP(con1, data, 2 + 2 + crypto_box_MACBYTES);
237 ck_assert_msg(len == 2, "wrong len %u", len);
238 ck_assert_msg(data[0] == 2, "wrong packet id %u", data[0]);
239 ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]);
240 len = read_packet_sec_TCP(con1, data, 2 + sizeof(test_packet) + crypto_box_MACBYTES);
241 ck_assert_msg(len == 1024, "wrong len %u", len);
242 ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong");
84} 243}
85END_TEST 244END_TEST
86 245
@@ -97,6 +256,7 @@ Suite *TCP_suite(void)
97 Suite *s = suite_create("TCP"); 256 Suite *s = suite_create("TCP");
98 257
99 DEFTESTCASE_SLOW(basic, 5); 258 DEFTESTCASE_SLOW(basic, 5);
259 DEFTESTCASE_SLOW(some, 10);
100 return s; 260 return s;
101} 261}
102 262
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index 9d0b0d31..620ff51b 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -309,6 +309,35 @@ static int read_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t
309 return len; 309 return len;
310} 310}
311 311
312/* return 0 if pending data was sent completely
313 * return -1 if it wasn't
314 */
315static int send_pending_data(TCP_Secure_Connection *con)
316{
317 if (con->last_packet_length == 0) {
318 return 0;
319 }
320
321 uint16_t left = con->last_packet_length - con->last_packet_sent;
322 int len = send(con->sock, con->last_packet + con->last_packet_sent, left, 0);
323
324 if (len <= 0)
325 return -1;
326
327 if (len == left) {
328 con->last_packet_length = 0;
329 con->last_packet_sent = 0;
330 return 0;
331 }
332
333 if (len > left)
334 return -1;
335
336 con->last_packet_sent += len;
337 return -1;
338
339}
340
312/* return 1 on success. 341/* return 1 on success.
313 * return 0 if could not send packet. 342 * return 0 if could not send packet.
314 * return -1 on failure (connection must be killed). 343 * return -1 on failure (connection must be killed).
@@ -318,26 +347,32 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_
318 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) 347 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
319 return -1; 348 return -1;
320 349
350 if (send_pending_data(con) == -1)
351 return 0;
352
321 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; 353 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
322 354
323 uint16_t c_length = htons(length) + crypto_box_MACBYTES; 355 uint16_t c_length = htons(length + crypto_box_MACBYTES);
324 memcpy(packet, &c_length, sizeof(uint16_t)); 356 memcpy(packet, &c_length, sizeof(uint16_t));
325 uint32_t len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); 357 int len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
326 358
327 if (len != (sizeof(packet) - sizeof(uint16_t))) 359 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
328 return -1; 360 return -1;
329 361
330 increment_nonce(con->sent_nonce); 362 increment_nonce(con->sent_nonce);
331 363
332 len = send(con->sock, packet, sizeof(packet), 0); 364 len = send(con->sock, packet, sizeof(packet), 0);
333 365
334 if (len == sizeof(packet)) 366 if ((unsigned int)len == sizeof(packet))
335 return 1; 367 return 1;
336 368
337 if (len <= 0) 369 if (len <= 0)
338 return 0; 370 return 0;
339 371
340 return -1; 372 memcpy(con->last_packet, packet, length);
373 con->last_packet_length = sizeof(packet);
374 con->last_packet_sent = len;
375 return 1;
341} 376}
342 377
343/* Kill a TCP_Secure_Connection 378/* Kill a TCP_Secure_Connection
@@ -368,6 +403,7 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint1
368 if (len != TCP_HANDSHAKE_PLAIN_SIZE) 403 if (len != TCP_HANDSHAKE_PLAIN_SIZE)
369 return -1; 404 return -1;
370 405
406 memcpy(con->public_key, data, crypto_box_PUBLICKEYBYTES);
371 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 407 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
372 uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE]; 408 uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
373 crypto_box_keypair(resp_plain, temp_secret_key); 409 crypto_box_keypair(resp_plain, temp_secret_key);
@@ -427,7 +463,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, uint8
427 */ 463 */
428static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id) 464static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
429{ 465{
430 uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id}; 466 uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id + NUM_RESERVED_PORTS};
431 return write_packet_TCP_secure_connection(con, data, sizeof(data)); 467 return write_packet_TCP_secure_connection(con, data, sizeof(data));
432} 468}
433 469
@@ -437,7 +473,7 @@ static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
437 */ 473 */
438static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) 474static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id)
439{ 475{
440 uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id}; 476 uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id + NUM_RESERVED_PORTS};
441 return write_packet_TCP_secure_connection(con, data, sizeof(data)); 477 return write_packet_TCP_secure_connection(con, data, sizeof(data));
442} 478}
443 479
@@ -450,6 +486,14 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8
450 uint32_t index = ~0; 486 uint32_t index = ~0;
451 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id]; 487 TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id];
452 488
489 /* If person tries to cennect to himself we deny the request*/
490 if (memcmp(con->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
491 if (send_routing_response(con, 0, public_key) == -1)
492 return -1;
493
494 return 0;
495 }
496
453 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) { 497 for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
454 if (con->connections[i].status == 0) { 498 if (con->connections[i].status == 0) {
455 index = i; 499 index = i;
@@ -464,7 +508,7 @@ static int handle_TCP_routing_req(TCP_Server *TCP_server, uint32_t con_id, uint8
464 return 0; 508 return 0;
465 } 509 }
466 510
467 int ret = send_routing_response(con, index, public_key); 511 int ret = send_routing_response(con, index + NUM_RESERVED_PORTS, public_key);
468 512
469 if (ret == 0) 513 if (ret == 0)
470 return 0; 514 return 0;
@@ -801,6 +845,7 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
801 if (conn->status != TCP_STATUS_CONFIRMED) 845 if (conn->status != TCP_STATUS_CONFIRMED)
802 continue; 846 continue;
803 847
848 send_pending_data(conn);
804 uint8_t packet[MAX_PACKET_SIZE]; 849 uint8_t packet[MAX_PACKET_SIZE];
805 int len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet)); 850 int len = read_packet_TCP_secure_connection(conn, packet, sizeof(packet));
806 851
diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h
index 22a992de..9bbfbe17 100644
--- a/toxcore/TCP_server.h
+++ b/toxcore/TCP_server.h
@@ -26,7 +26,7 @@
26 26
27#define TCP_MAX_BACKLOG MAX_INCOMMING_CONNECTIONS 27#define TCP_MAX_BACKLOG MAX_INCOMMING_CONNECTIONS
28 28
29#define MAX_PACKET_SIZE 8192 29#define MAX_PACKET_SIZE 2048
30 30
31#define TCP_HANDSHAKE_PLAIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES) 31#define TCP_HANDSHAKE_PLAIN_SIZE (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES)
32#define TCP_SERVER_HANDSHAKE_SIZE (crypto_box_NONCEBYTES + TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES) 32#define TCP_SERVER_HANDSHAKE_SIZE (crypto_box_NONCEBYTES + TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES)
@@ -65,6 +65,9 @@ typedef struct TCP_Secure_Connection {
65 uint32_t index; 65 uint32_t index;
66 uint8_t other_id; 66 uint8_t other_id;
67 } connections[NUM_CLIENT_CONNECTIONS]; 67 } connections[NUM_CLIENT_CONNECTIONS];
68 uint8_t last_packet[2 + MAX_PACKET_SIZE];
69 uint16_t last_packet_length;
70 uint16_t last_packet_sent;
68} TCP_Secure_Connection; 71} TCP_Secure_Connection;
69 72
70 73