diff options
Diffstat (limited to 'transport.c')
-rw-r--r-- | transport.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/transport.c b/transport.c new file mode 100644 index 0000000..fea3e7e --- /dev/null +++ b/transport.c @@ -0,0 +1,99 @@ +#include <stdio.h> +#include <string.h> +#include <sodium.h> +#include "transport.h" +#include "net.h" + +#define STREAM_KEY_SIZE 32 +#define STREAM_HEADER_SIZE 24 +#define PARTY_PUBKEY_SIZE 32 +#define PARTY_SECKEY_SIZE 32 + + +__attribute__((warn_unused_result)) +static bool check_libsodium_size_assumptions(void) { + return + crypto_secretstream_xchacha20poly1305_KEYBYTES == STREAM_KEY_SIZE && + crypto_secretstream_xchacha20poly1305_HEADERBYTES == STREAM_HEADER_SIZE && + crypto_kx_SESSIONKEYBYTES >= STREAM_KEY_SIZE && + crypto_kx_PUBLICKEYBYTES == PARTY_PUBKEY_SIZE && + crypto_kx_SECRETKEYBYTES == PARTY_SECKEY_SIZE; +} + +static void send_clienthello( + int fd, + const unsigned char pubkey[PARTY_PUBKEY_SIZE] +) { + char buffer[16 + PARTY_PUBKEY_SIZE]; + memcpy(buffer, "tomsg v01 client", 16); + memcpy(buffer + 16, pubkey, PARTY_PUBKEY_SIZE); + net_send_raw_text(fd, buffer, sizeof buffer); +} + +static void send_serverhello( + int fd, + const unsigned char pubkey[PARTY_PUBKEY_SIZE], + const unsigned char server_tx_header[STREAM_HEADER_SIZE] +) { + char buffer[16 + PARTY_PUBKEY_SIZE + STREAM_HEADER_SIZE]; + memcpy(buffer, "tomsg v01 server", 16); + memcpy(buffer + 16, pubkey, PARTY_PUBKEY_SIZE); + memcpy(buffer + 16 + PARTY_PUBKEY_SIZE, server_tx_header, STREAM_HEADER_SIZE); + net_send_raw_text(fd, buffer, sizeof buffer); +} + +static void send_clienthello2( + int fd, + const unsigned char client_tx_header[STREAM_HEADER_SIZE] +) { + char buffer[8 + STREAM_HEADER_SIZE]; + memcpy(buffer, "cheader0", 8); + memcpy(buffer + 8, client_tx_header, STREAM_HEADER_SIZE); + net_send_raw_text(fd, buffer, sizeof buffer); +} + + +enum phase { + WAITING_FOR_SERVERHELLO, + WAITING_FOR_CLIENTHELLO, + WAITING_FOR_CLIENTHELLO2, + WAITING_FOR_DATA, // handshake finished +}; + +struct transport { + int fd; + bool is_server; + enum phase phase; + unsigned char my_pubkey[PARTY_PUBKEY_SIZE]; + unsigned char my_seckey[PARTY_SECKEY_SIZE]; + unsigned char other_pubkey[PARTY_PUBKEY_SIZE]; + crypto_secretstream_xchacha20poly1305_state pushstate; + crypto_secretstream_xchacha20poly1305_state pullstate; +}; + +struct transport* tsp_start(int fd, bool is_server) { + if (!check_libsodium_size_assumptions()) { + die("Transport protocol size assumptions do not hold!"); + } + + struct transport *tsp = calloc(1, struct transport); + tsp->fd = fd; + tsp->is_server = is_server; + + crypto_kx_keypair(tsp->my_pubkey, tsp->my_seckey); + + if (is_server) { + tsp->phase = WAITING_FOR_CLIENTHELLO; + } else { + send_clienthello(fd, tsp->my_pubkey); + tsp->phase = WAITING_FOR_SERVERHELLO; + } + + return tsp; +} + +void tsp_close(struct transport *tsp) { + if (tsp->phase == WAITING_FOR_DATA) { + + } +} |