summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-04-30 20:53:43 -0400
committerirungentoo <irungentoo@gmail.com>2014-04-30 20:53:43 -0400
commit5715e5016940abab7009f093a7c0785440dd2de8 (patch)
treec4b2a8ab6dc7de83d07312adc420da88188eccc5 /toxcore
parent0505df009bc01ef7db6e31ee6ea999aaa83b8bfc (diff)
Some more code written for the middle level protocol stuff.
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/net_crypto.c216
-rw-r--r--toxcore/net_crypto.h7
2 files changed, 218 insertions, 5 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 71959c46..3f74cf04 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -46,6 +46,8 @@ static uint8_t crypt_connection_id_not_valid(Net_Crypto *c, int crypt_connection
46#define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + sizeof(uint64_t) + crypto_box_MACBYTES) 46#define COOKIE_RESPONSE_LENGTH (1 + crypto_box_NONCEBYTES + COOKIE_LENGTH + sizeof(uint64_t) + crypto_box_MACBYTES)
47 47
48/* Create a cookie request packet and put it in packet. 48/* Create a cookie request packet and put it in packet.
49 * dht_public_key is the dht public key of the other
50 * real_public_key is the real public key of the other.
49 * 51 *
50 * packet must be of size COOKIE_REQUEST_LENGTH or bigger. 52 * packet must be of size COOKIE_REQUEST_LENGTH or bigger.
51 * 53 *
@@ -426,7 +428,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint
426 428
427 switch (packet[0]) { 429 switch (packet[0]) {
428 case NET_PACKET_COOKIE_RESPONSE: { 430 case NET_PACKET_COOKIE_RESPONSE: {
429 if (conn->status != CRYPTO_CONN_COOKIE_REQUESTED) 431 if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING)
430 return -1; 432 return -1;
431 433
432 uint8_t cookie[COOKIE_LENGTH]; 434 uint8_t cookie[COOKIE_LENGTH];
@@ -453,7 +455,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint
453 } 455 }
454 456
455 case NET_PACKET_CRYPTO_HS: { 457 case NET_PACKET_CRYPTO_HS: {
456 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTED || conn->status == CRYPTO_CONN_HANDSHAKE_SENT) { 458 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT) {
457 uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES]; 459 uint8_t peer_real_pk[crypto_box_PUBLICKEYBYTES];
458 uint8_t cookie[COOKIE_LENGTH]; 460 uint8_t cookie[COOKIE_LENGTH];
459 461
@@ -489,6 +491,95 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint
489 return 0; 491 return 0;
490} 492}
491 493
494/* Set the size of the friend list to numfriends.
495 *
496 * return -1 if realloc fails.
497 * return 0 if it succeeds.
498 */
499static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
500{
501 if (num == 0) {
502 free(c->crypto_connections);
503 c->crypto_connections = NULL;
504 return 0;
505 }
506
507 Crypto_Connection *newcrypto_connections = realloc(c->crypto_connections, num * sizeof(Crypto_Connection));
508
509 if (newcrypto_connections == NULL)
510 return -1;
511
512 c->crypto_connections = newcrypto_connections;
513 return 0;
514}
515
516
517/* Create a new empty crypto connection.
518 *
519 * return -1 on failure.
520 * return connection id on success.
521 */
522static int create_crypto_connection(Net_Crypto *c)
523{
524 uint32_t i;
525
526 for (i = 0; i <= c->crypto_connections_length; ++i) {
527 if (c->crypto_connections[i].status == CRYPTO_CONN_NO_CONNECTION)
528 return i;
529 }
530
531 if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1)
532 return -1;
533
534 memset(&(c->crypto_connections[c->crypto_connections_length]), 0, sizeof(Crypto_Connection));
535 int id = c->crypto_connections_length;
536 ++c->crypto_connections_length;
537 return id;
538}
539
540/* Wipe a crypto connection.
541 *
542 * return -1 on failure.
543 * return 0 on success.
544 */
545static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
546{
547 if (crypt_connection_id_not_valid(c, crypt_connection_id))
548 return -1;
549
550 uint32_t i;
551 memset(&(c->crypto_connections[crypt_connection_id]), 0 , sizeof(Crypto_Connection));
552
553 for (i = c->crypto_connections_length; i != 0; --i) {
554 if (c->crypto_connections[i - 1].status != CRYPTO_CONN_NO_CONNECTION)
555 break;
556 }
557
558 if (c->crypto_connections_length != i) {
559 c->crypto_connections_length = i;
560 realloc_cryptoconnection(c, c->crypto_connections_length);
561 }
562
563 return 0;
564}
565
566/* Get crypto connection id from public key of peer.
567 *
568 * return -1 if there are no connections like we are looking for.
569 * return id if it found it.
570 */
571static int getcryptconnection_id(Net_Crypto *c, uint8_t *public_key)
572{
573 uint32_t i;
574
575 for (i = 0; i < c->crypto_connections_length; ++i) {
576 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION)
577 if (memcmp(public_key, c->crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
578 return i;
579 }
580
581 return -1;
582}
492 583
493void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c), 584void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *object, New_Connection *n_c),
494 void *object) 585 void *object)
@@ -497,17 +588,136 @@ void new_connection_handler(Net_Crypto *c, int (*new_connection_callback)(void *
497 c->new_connection_callback_object = object; 588 c->new_connection_callback_object = object;
498} 589}
499 590
500static int handle_new_connection_handshake(Net_Crypto *c, uint8_t *data, uint16_t length) 591/* Handle a handshake packet by someone who wants to initiate a new connection with us.
592 * This calls the callback set by new_connection_handler() if the handshake is ok.
593 *
594 * return -1 on failure.
595 * return 0 on success.
596 */
597static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, uint8_t *data, uint16_t length)
501{ 598{
599 New_Connection n_c;
600 n_c.cookie = malloc(COOKIE_LENGTH);
502 601
602 if (n_c.cookie == NULL)
603 return -1;
604
605 n_c.source = source;
606 n_c.cookie_length = COOKIE_LENGTH;
607
608 if (handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.cookie, data, length,
609 0) != 0)
610 return -1;
503 611
612 return c->new_connection_callback(c->new_connection_callback_object, &n_c);
504} 613}
505 614
615/* Accept a crypto connection.
616 *
617 * return -1 on failure.
618 * return connection id on success.
619 */
506int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) 620int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
507{ 621{
622 //TODO: do something with n_c->source.
623 if (getcryptconnection_id(c, n_c->public_key) != -1)
624 return -1;
625
626 int crypt_connection_id = create_crypto_connection(c);
627
628 if (crypt_connection_id == -1)
629 return -1;
630
631 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
632
633 if (conn == 0)
634 return -1;
635
636 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
637 memcpy(conn->recv_nonce, n_c->recv_nonce, crypto_box_NONCEBYTES);
638 memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
639 random_nonce(conn->sent_nonce);
640 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
641 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
642
643 if (n_c->cookie_length != COOKIE_LENGTH)
644 return -1;
645
646 uint8_t handshake_packet[HANDSHAKE_PACKET_LENGTH];
647
648 if (create_crypto_handshake(c, handshake_packet, n_c->cookie, conn->sent_nonce, conn->sessionpublic_key,
649 conn->public_key) != sizeof(handshake_packet))
650 return -1;
651
652 if (new_temp_packet(c, crypt_connection_id, handshake_packet, sizeof(handshake_packet)) != 0)
653 return -1;
654
655 send_temp_packet(c, crypt_connection_id);
656 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
657 return crypt_connection_id;
658}
659
660/* Create a crypto connection.
661 * If one to that real public key already exists, return it.
662 *
663 * return -1 on failure.
664 * return connection id on success.
665 */
666int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key)
667{
668 int crypt_connection_id = getcryptconnection_id(c, real_public_key);
669
670 if (crypt_connection_id != -1)
671 return crypt_connection_id;
672
673 crypt_connection_id = create_crypto_connection(c);
674
675 if (crypt_connection_id == -1)
676 return -1;
677
678 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
679
680 if (conn == 0)
681 return -1;
682
683 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
684 random_nonce(conn->sent_nonce);
685 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
686 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
687 return crypt_connection_id;
688}
689
690/* Set the DHT public key of the crypto connection.
691 * If one to that real public key already exists, return it.
692 *
693 * return -1 on failure.
694 * return 0 on success.
695 */
696int set_conection_dht_public_key(Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
697{
698 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
508 699
700 if (conn == 0)
701 return -1;
509 702
703 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
704 conn->dht_public_key_set = 1;
705
706 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
707 conn->cookie_request_number = random_64b();
708 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
709
710 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->public_key,
711 conn->cookie_request_number) != sizeof(cookie_request))
712 return -1;
713
714 if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0)
715 return -1;
716 }//TODO
717
718 return 0;
510} 719}
720
511/* return 0 if there is no received data in the buffer. 721/* return 0 if there is no received data in the buffer.
512 * return -1 if the packet was discarded. 722 * return -1 if the packet was discarded.
513 * return length of received data if successful. 723 * return length of received data if successful.
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 8dac937e..0d27ae4d 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -30,7 +30,7 @@
30#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2) 30#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
31 31
32#define CRYPTO_CONN_NO_CONNECTION 0 32#define CRYPTO_CONN_NO_CONNECTION 0
33#define CRYPTO_CONN_COOKIE_REQUESTED 1 //send cookie request packets 33#define CRYPTO_CONN_COOKIE_REQUESTING 1 //send cookie request packets
34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets 34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets 35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets
36#define CRYPTO_CONN_ESTABLISHED 4 36#define CRYPTO_CONN_ESTABLISHED 4
@@ -39,7 +39,7 @@
39#define CRYPTO_PACKET_BUFFER_SIZE 64 39#define CRYPTO_PACKET_BUFFER_SIZE 64
40 40
41#define MAX_CRYPTO_PACKET_SIZE 1400 41#define MAX_CRYPTO_PACKET_SIZE 1400
42 42#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
43typedef struct { 43typedef struct {
44 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 44 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
45 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */ 45 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
@@ -58,6 +58,8 @@ typedef struct {
58 uint64_t timeout; 58 uint64_t timeout;
59 59
60 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ 60 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
61 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
62 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
61 63
62 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ 64 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
63 uint16_t temp_packet_length; 65 uint16_t temp_packet_length;
@@ -65,6 +67,7 @@ typedef struct {
65} Crypto_Connection; 67} Crypto_Connection;
66 68
67typedef struct { 69typedef struct {
70 IP_Port source;
68 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 71 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
69 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */ 72 uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */
70 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */ 73 uint8_t peersessionpublic_key[crypto_box_PUBLICKEYBYTES]; /* The public key of the peer. */