summaryrefslogtreecommitdiff
path: root/toxcore/net_crypto.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-04-23 11:35:40 -0400
committerirungentoo <irungentoo@gmail.com>2014-04-23 11:35:40 -0400
commit384750af8cf9e339989ded452181e1238ed6e307 (patch)
treef3eb8ac28b07263fe4c8372db8a2f52230531133 /toxcore/net_crypto.c
parent1bfe15ee88844bdbd43052b4026202cf924ad6ca (diff)
Major cleanups.
Fixed circular dependency between DHT and net_crypto: DHT no longer depends on net_crypto. Moved the crypto request packets functions to crypto core and DHT. Cleaned up/added some defines that can be used to get the true maximum length of things like the friends request message. MAX_DATA_SIZE has been replaced in most places by more appropriate defines.
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r--toxcore/net_crypto.c120
1 files changed, 4 insertions, 116 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 3eb9ca4c..2136e09f 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -249,113 +249,6 @@ int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uin
249 return 1; 249 return 1;
250} 250}
251 251
252/* Create a request to peer.
253 * send_public_key and send_secret_key are the pub/secret keys of the sender.
254 * recv_public_key is public key of reciever.
255 * packet must be an array of MAX_DATA_SIZE big.
256 * Data represents the data we send with the request with length being the length of the data.
257 * request_id is the id of the request (32 = friend request, 254 = ping request).
258 *
259 * return -1 on failure.
260 * return the length of the created packet on success.
261 */
262int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
263 uint8_t *data, uint32_t length, uint8_t request_id)
264{
265 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES)
266 return -1;
267
268 uint8_t nonce[crypto_box_NONCEBYTES];
269 uint8_t temp[MAX_DATA_SIZE];
270 memcpy(temp + 1, data, length);
271 temp[0] = request_id;
272 new_nonce(nonce);
273 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
274 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
275
276 if (len == -1)
277 return -1;
278
279 packet[0] = NET_PACKET_CRYPTO;
280 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
281 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
282 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
283
284 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
285}
286
287/* Puts the senders public key in the request in public_key, the data from the request
288 * in data if a friend or ping request was sent to us and returns the length of the data.
289 * packet is the request packet and length is its length.
290 *
291 * return -1 if not valid request.
292 */
293int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
294 uint8_t *request_id, uint8_t *packet, uint16_t length)
295{
296 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
297 length <= MAX_DATA_SIZE) {
298 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
299 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
300 uint8_t nonce[crypto_box_NONCEBYTES];
301 uint8_t temp[MAX_DATA_SIZE];
302 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
303 int len1 = decrypt_data(public_key, self_secret_key, nonce,
304 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
305 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
306
307 if (len1 == -1 || len1 == 0)
308 return -1;
309
310 request_id[0] = temp[0];
311 --len1;
312 memcpy(data, temp + 1, len1);
313 return len1;
314 }
315 }
316
317 return -1;
318}
319
320void cryptopacket_registerhandler(Net_Crypto *c, uint8_t byte, cryptopacket_handler_callback cb, void *object)
321{
322 c->cryptopackethandlers[byte].function = cb;
323 c->cryptopackethandlers[byte].object = object;
324}
325
326static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length)
327{
328 DHT *dht = object;
329
330 if (packet[0] == NET_PACKET_CRYPTO) {
331 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES ||
332 length > MAX_DATA_SIZE + crypto_box_MACBYTES)
333 return 1;
334
335 if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
336 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
337 uint8_t data[MAX_DATA_SIZE];
338 uint8_t number;
339 int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
340
341 if (len == -1 || len == 0)
342 return 1;
343
344 if (!dht->c->cryptopackethandlers[number].function) return 1;
345
346 return dht->c->cryptopackethandlers[number].function(dht->c->cryptopackethandlers[number].object, source, public_key,
347 data, len);
348
349 } else { /* If request is not for us, try routing it. */
350 int retval = route_packet(dht, packet + 1, packet, length);
351
352 if ((unsigned int)retval == length)
353 return 0;
354 }
355 }
356
357 return 1;
358}
359 252
360/* Send a crypto handshake packet containing an encrypted secret nonce and session public key 253/* Send a crypto handshake packet containing an encrypted secret nonce and session public key
361 * to peer with connection_id and public_key. 254 * to peer with connection_id and public_key.
@@ -774,11 +667,11 @@ static void receive_crypto(Net_Crypto *c)
774/* Run this to (re)initialize net_crypto. 667/* Run this to (re)initialize net_crypto.
775 * Sets all the global connection variables to their default values. 668 * Sets all the global connection variables to their default values.
776 */ 669 */
777Net_Crypto *new_net_crypto(Networking_Core *net) 670Net_Crypto *new_net_crypto(DHT *dht)
778{ 671{
779 unix_time_update(); 672 unix_time_update();
780 673
781 if (net == NULL) 674 if (dht == NULL)
782 return NULL; 675 return NULL;
783 676
784 Net_Crypto *temp = calloc(1, sizeof(Net_Crypto)); 677 Net_Crypto *temp = calloc(1, sizeof(Net_Crypto));
@@ -786,7 +679,8 @@ Net_Crypto *new_net_crypto(Networking_Core *net)
786 if (temp == NULL) 679 if (temp == NULL)
787 return NULL; 680 return NULL;
788 681
789 temp->lossless_udp = new_lossless_udp(net); 682 temp->dht = dht;
683 temp->lossless_udp = new_lossless_udp(dht->net);
790 684
791 if (temp->lossless_udp == NULL) { 685 if (temp->lossless_udp == NULL) {
792 free(temp); 686 free(temp);
@@ -798,12 +692,6 @@ Net_Crypto *new_net_crypto(Networking_Core *net)
798 return temp; 692 return temp;
799} 693}
800 694
801void init_cryptopackets(void *dht)
802{
803 DHT *s_dht = dht;
804 networking_registerhandler(s_dht->c->lossless_udp->net, NET_PACKET_CRYPTO, &cryptopacket_handle, s_dht);
805}
806
807static void kill_timedout(Net_Crypto *c) 695static void kill_timedout(Net_Crypto *c)
808{ 696{
809 uint32_t i; 697 uint32_t i;