diff options
Diffstat (limited to 'src/transport/gnunet-communicator-tcp.c')
-rw-r--r-- | src/transport/gnunet-communicator-tcp.c | 93 |
1 files changed, 49 insertions, 44 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c index e2f1e4507..1273465c3 100644 --- a/src/transport/gnunet-communicator-tcp.c +++ b/src/transport/gnunet-communicator-tcp.c | |||
@@ -82,9 +82,9 @@ | |||
82 | 82 | ||
83 | /** | 83 | /** |
84 | * How often do we rekey based on number of bytes transmitted? | 84 | * How often do we rekey based on number of bytes transmitted? |
85 | * (additionally randomized). | 85 | * (additionally randomized). Currently 400 MB |
86 | */ | 86 | */ |
87 | #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU) | 87 | #define REKEY_MAX_BYTES (1024LLU * 1024 * 400) |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Size of the initial key exchange message sent first in both | 90 | * Size of the initial key exchange message sent first in both |
@@ -469,12 +469,6 @@ struct Queue | |||
469 | struct GNUNET_HashCode out_hmac; | 469 | struct GNUNET_HashCode out_hmac; |
470 | 470 | ||
471 | /** | 471 | /** |
472 | * Our ephemeral key. Stored here temporarily during rekeying / key | ||
473 | * generation. | ||
474 | */ | ||
475 | struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral; | ||
476 | |||
477 | /** | ||
478 | * ID of read task for this connection. | 472 | * ID of read task for this connection. |
479 | */ | 473 | */ |
480 | struct GNUNET_SCHEDULER_Task *read_task; | 474 | struct GNUNET_SCHEDULER_Task *read_task; |
@@ -667,6 +661,17 @@ struct Queue | |||
667 | * Store Context for retrieving the monotonic time send with the handshake ack. | 661 | * Store Context for retrieving the monotonic time send with the handshake ack. |
668 | */ | 662 | */ |
669 | struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc; | 663 | struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc; |
664 | |||
665 | /** | ||
666 | * Size of data received without KX challenge played back. | ||
667 | */ | ||
668 | // TODO remove? | ||
669 | size_t unverified_size; | ||
670 | |||
671 | /** | ||
672 | * Has the initial (core) handshake already happened? | ||
673 | */ | ||
674 | int initial_core_kx_done; | ||
670 | }; | 675 | }; |
671 | 676 | ||
672 | 677 | ||
@@ -893,11 +898,6 @@ struct ListenTask *lts_tail; | |||
893 | */ | 898 | */ |
894 | int addrs_lens; | 899 | int addrs_lens; |
895 | 900 | ||
896 | /** | ||
897 | * Size of data received without KX challenge played back. | ||
898 | */ | ||
899 | // TODO remove? | ||
900 | size_t unverified_size; | ||
901 | 901 | ||
902 | /** | 902 | /** |
903 | * Database for peer's HELLOs. | 903 | * Database for peer's HELLOs. |
@@ -1357,10 +1357,10 @@ static void | |||
1357 | setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, | 1357 | setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, |
1358 | struct Queue *queue) | 1358 | struct Queue *queue) |
1359 | { | 1359 | { |
1360 | struct GNUNET_HashCode dh; | 1360 | struct GNUNET_HashCode k; |
1361 | 1361 | ||
1362 | GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh); | 1362 | GNUNET_CRYPTO_eddsa_kem_decaps (my_private_key, ephemeral, &k); |
1363 | setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac); | 1363 | setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac); |
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | 1366 | ||
@@ -1557,14 +1557,9 @@ send_challenge (struct GNUNET_CRYPTO_ChallengeNonceP challenge, | |||
1557 | * @param queue queue to setup outgoing (encryption) cipher for | 1557 | * @param queue queue to setup outgoing (encryption) cipher for |
1558 | */ | 1558 | */ |
1559 | static void | 1559 | static void |
1560 | setup_out_cipher (struct Queue *queue) | 1560 | setup_out_cipher (struct Queue *queue, struct GNUNET_HashCode *dh) |
1561 | { | 1561 | { |
1562 | struct GNUNET_HashCode dh; | 1562 | setup_cipher (dh, &queue->target, &queue->out_cipher, &queue->out_hmac); |
1563 | |||
1564 | GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh); | ||
1565 | /* we don't need the private key anymore, drop it! */ | ||
1566 | memset (&queue->ephemeral, 0, sizeof(queue->ephemeral)); | ||
1567 | setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac); | ||
1568 | queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval); | 1563 | queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval); |
1569 | queue->rekey_left_bytes = | 1564 | queue->rekey_left_bytes = |
1570 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES); | 1565 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES); |
@@ -1582,13 +1577,14 @@ inject_rekey (struct Queue *queue) | |||
1582 | { | 1577 | { |
1583 | struct TCPRekey rekey; | 1578 | struct TCPRekey rekey; |
1584 | struct TcpRekeySignature thp; | 1579 | struct TcpRekeySignature thp; |
1580 | struct GNUNET_HashCode k; | ||
1585 | 1581 | ||
1586 | GNUNET_assert (0 == queue->pwrite_off); | 1582 | GNUNET_assert (0 == queue->pwrite_off); |
1587 | memset (&rekey, 0, sizeof(rekey)); | 1583 | memset (&rekey, 0, sizeof(rekey)); |
1588 | GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral); | 1584 | GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &rekey.ephemeral, |
1585 | &k); | ||
1589 | rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY); | 1586 | rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY); |
1590 | rekey.header.size = ntohs (sizeof(rekey)); | 1587 | rekey.header.size = ntohs (sizeof(rekey)); |
1591 | GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral); | ||
1592 | rekey.monotonic_time = | 1588 | rekey.monotonic_time = |
1593 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); | 1589 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); |
1594 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY); | 1590 | thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY); |
@@ -1627,9 +1623,10 @@ inject_rekey (struct Queue *queue) | |||
1627 | queue->cwrite_off += sizeof(rekey); | 1623 | queue->cwrite_off += sizeof(rekey); |
1628 | /* Setup new cipher for successive messages */ | 1624 | /* Setup new cipher for successive messages */ |
1629 | gcry_cipher_close (queue->out_cipher); | 1625 | gcry_cipher_close (queue->out_cipher); |
1630 | setup_out_cipher (queue); | 1626 | setup_out_cipher (queue, &k); |
1631 | } | 1627 | } |
1632 | 1628 | ||
1629 | |||
1633 | static int | 1630 | static int |
1634 | pending_reversals_delete_it (void *cls, | 1631 | pending_reversals_delete_it (void *cls, |
1635 | const struct GNUNET_HashCode *key, | 1632 | const struct GNUNET_HashCode *key, |
@@ -1829,7 +1826,7 @@ queue_write (void *cls) | |||
1829 | if (((0 == queue->rekey_left_bytes) || | 1826 | if (((0 == queue->rekey_left_bytes) || |
1830 | (0 == GNUNET_TIME_absolute_get_remaining ( | 1827 | (0 == GNUNET_TIME_absolute_get_remaining ( |
1831 | queue->rekey_time).rel_value_us)) && | 1828 | queue->rekey_time).rel_value_us)) && |
1832 | (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey)&& | 1829 | (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey) && |
1833 | (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE))) | 1830 | (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE))) |
1834 | { | 1831 | { |
1835 | inject_rekey (queue); | 1832 | inject_rekey (queue); |
@@ -1868,24 +1865,23 @@ queue_write (void *cls) | |||
1868 | static size_t | 1865 | static size_t |
1869 | try_handle_plaintext (struct Queue *queue) | 1866 | try_handle_plaintext (struct Queue *queue) |
1870 | { | 1867 | { |
1871 | const struct GNUNET_MessageHeader *hdr = | 1868 | const struct GNUNET_MessageHeader *hdr; |
1872 | (const struct GNUNET_MessageHeader *) queue->pread_buf; | 1869 | const struct TCPConfirmationAck *tca; |
1873 | const struct TCPConfirmationAck *tca = (const struct | 1870 | const struct TCPBox *box; |
1874 | TCPConfirmationAck *) queue->pread_buf; | 1871 | const struct TCPRekey *rekey; |
1875 | const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf; | 1872 | const struct TCPFinish *fin; |
1876 | const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf; | ||
1877 | const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf; | ||
1878 | struct TCPRekey rekeyz; | 1873 | struct TCPRekey rekeyz; |
1879 | struct TCPFinish finz; | 1874 | struct TCPFinish finz; |
1880 | struct GNUNET_ShortHashCode tmac; | 1875 | struct GNUNET_ShortHashCode tmac; |
1881 | uint16_t type; | 1876 | uint16_t type; |
1882 | size_t size = 0; /* make compiler happy */ | 1877 | size_t size = 0; |
1883 | struct TcpHandshakeAckSignature thas; | 1878 | struct TcpHandshakeAckSignature thas; |
1884 | const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge; | 1879 | const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge; |
1885 | 1880 | ||
1886 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1881 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1887 | "try handle plaintext!\n"); | 1882 | "try handle plaintext!\n"); |
1888 | 1883 | ||
1884 | hdr = (const struct GNUNET_MessageHeader *) queue->pread_buf; | ||
1889 | if ((sizeof(*hdr) > queue->pread_off)) | 1885 | if ((sizeof(*hdr) > queue->pread_off)) |
1890 | { | 1886 | { |
1891 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1887 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1893,11 +1889,12 @@ try_handle_plaintext (struct Queue *queue) | |||
1893 | return 0; /* not even a header */ | 1889 | return 0; /* not even a header */ |
1894 | } | 1890 | } |
1895 | 1891 | ||
1896 | if ((-1 != unverified_size) && (unverified_size > INITIAL_CORE_KX_SIZE)) | 1892 | if ((GNUNET_YES != queue->initial_core_kx_done) && (queue->unverified_size > |
1893 | INITIAL_CORE_KX_SIZE)) | ||
1897 | { | 1894 | { |
1898 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1895 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1899 | "Already received data of size %lu bigger than KX size %lu!\n", | 1896 | "Already received data of size %lu bigger than KX size %lu!\n", |
1900 | unverified_size, | 1897 | queue->unverified_size, |
1901 | INITIAL_CORE_KX_SIZE); | 1898 | INITIAL_CORE_KX_SIZE); |
1902 | GNUNET_break_op (0); | 1899 | GNUNET_break_op (0); |
1903 | queue_finish (queue); | 1900 | queue_finish (queue); |
@@ -1908,6 +1905,7 @@ try_handle_plaintext (struct Queue *queue) | |||
1908 | switch (type) | 1905 | switch (type) |
1909 | { | 1906 | { |
1910 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK: | 1907 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK: |
1908 | tca = (const struct TCPConfirmationAck *) queue->pread_buf; | ||
1911 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1909 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1912 | "start processing ack\n"); | 1910 | "start processing ack\n"); |
1913 | if (sizeof(*tca) > queue->pread_off) | 1911 | if (sizeof(*tca) > queue->pread_off) |
@@ -1980,7 +1978,11 @@ try_handle_plaintext (struct Queue *queue) | |||
1980 | queue->address->sa_family, NULL); | 1978 | queue->address->sa_family, NULL); |
1981 | } | 1979 | } |
1982 | 1980 | ||
1983 | unverified_size = -1; | 1981 | /** |
1982 | * Once we received this ack, we consider this a verified connection. | ||
1983 | * FIXME: I am not sure this logic is sane here. | ||
1984 | */ | ||
1985 | queue->initial_core_kx_done = GNUNET_YES; | ||
1984 | 1986 | ||
1985 | char *foreign_addr; | 1987 | char *foreign_addr; |
1986 | 1988 | ||
@@ -2020,6 +2022,7 @@ try_handle_plaintext (struct Queue *queue) | |||
2020 | break; | 2022 | break; |
2021 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX: | 2023 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX: |
2022 | /* Special case: header size excludes box itself! */ | 2024 | /* Special case: header size excludes box itself! */ |
2025 | box = (const struct TCPBox *) queue->pread_buf; | ||
2023 | if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off) | 2026 | if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off) |
2024 | return 0; | 2027 | return 0; |
2025 | calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac); | 2028 | calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac); |
@@ -2036,6 +2039,7 @@ try_handle_plaintext (struct Queue *queue) | |||
2036 | break; | 2039 | break; |
2037 | 2040 | ||
2038 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY: | 2041 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY: |
2042 | rekey = (const struct TCPRekey *) queue->pread_buf; | ||
2039 | if (sizeof(*rekey) > queue->pread_off) | 2043 | if (sizeof(*rekey) > queue->pread_off) |
2040 | return 0; | 2044 | return 0; |
2041 | if (ntohs (hdr->size) != sizeof(*rekey)) | 2045 | if (ntohs (hdr->size) != sizeof(*rekey)) |
@@ -2060,6 +2064,7 @@ try_handle_plaintext (struct Queue *queue) | |||
2060 | break; | 2064 | break; |
2061 | 2065 | ||
2062 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH: | 2066 | case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH: |
2067 | fin = (const struct TCPFinish *) queue->pread_buf; | ||
2063 | if (sizeof(*fin) > queue->pread_off) | 2068 | if (sizeof(*fin) > queue->pread_off) |
2064 | return 0; | 2069 | return 0; |
2065 | if (ntohs (hdr->size) != sizeof(*fin)) | 2070 | if (ntohs (hdr->size) != sizeof(*fin)) |
@@ -2091,8 +2096,8 @@ try_handle_plaintext (struct Queue *queue) | |||
2091 | return 0; | 2096 | return 0; |
2092 | } | 2097 | } |
2093 | GNUNET_assert (0 != size); | 2098 | GNUNET_assert (0 != size); |
2094 | if (-1 != unverified_size) | 2099 | if (-1 != queue->unverified_size) |
2095 | unverified_size += size; | 2100 | queue->unverified_size += size; |
2096 | return size; | 2101 | return size; |
2097 | } | 2102 | } |
2098 | 2103 | ||
@@ -2712,10 +2717,10 @@ static void | |||
2712 | start_initial_kx_out (struct Queue *queue) | 2717 | start_initial_kx_out (struct Queue *queue) |
2713 | { | 2718 | { |
2714 | struct GNUNET_CRYPTO_EcdhePublicKey epub; | 2719 | struct GNUNET_CRYPTO_EcdhePublicKey epub; |
2720 | struct GNUNET_HashCode k; | ||
2715 | 2721 | ||
2716 | GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral); | 2722 | GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &epub, &k); |
2717 | GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &epub); | 2723 | setup_out_cipher (queue, &k); |
2718 | setup_out_cipher (queue); | ||
2719 | transmit_kx (queue, &epub); | 2724 | transmit_kx (queue, &epub); |
2720 | } | 2725 | } |
2721 | 2726 | ||
@@ -3060,6 +3065,7 @@ proto_read_kx (void *cls) | |||
3060 | GNUNET_free (pq); | 3065 | GNUNET_free (pq); |
3061 | } | 3066 | } |
3062 | 3067 | ||
3068 | |||
3063 | static struct ProtoQueue * | 3069 | static struct ProtoQueue * |
3064 | create_proto_queue (struct GNUNET_NETWORK_Handle *sock, | 3070 | create_proto_queue (struct GNUNET_NETWORK_Handle *sock, |
3065 | struct sockaddr *in, | 3071 | struct sockaddr *in, |
@@ -3120,7 +3126,6 @@ listen_cb (void *cls) | |||
3120 | struct sockaddr_storage in; | 3126 | struct sockaddr_storage in; |
3121 | socklen_t addrlen; | 3127 | socklen_t addrlen; |
3122 | struct GNUNET_NETWORK_Handle *sock; | 3128 | struct GNUNET_NETWORK_Handle *sock; |
3123 | struct ProtoQueue *pq; | ||
3124 | struct ListenTask *lt; | 3129 | struct ListenTask *lt; |
3125 | struct sockaddr *in_addr; | 3130 | struct sockaddr *in_addr; |
3126 | 3131 | ||