aboutsummaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c99
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) {
+
+ }
+}