diff --git a/src/main.c b/src/main.c index 31245d1..40c8e85 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -12,177 +13,187 @@ #define CHANNELS 1 #define SAMPLE_RATE 48000 #define FRAMES_PER_BUFFFER 960 +#define AUDIO_BUF_SIZE (FRAMES_PER_BUFFFER * CHANNELS) -#define BUF_SIZE (FRAMES_PER_BUFFFER * CHANNELS) +#define NET_BUF_SIZE 1024 + +#define MSG_HSFUCKOFF "HSFUCKOFF" +#define MSG_HSFUCKOFF_LEN 9 + +#define MSG_HSACK "HSACK" +#define MSG_HSACK_LEN 5 + +int client_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk); +int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk); + +void usage(void) { + fprintf(stderr, "A Sodium cryptography library is failed to initialise!\n"); +} int main(int argc, char **argv) { - (void)argv; - (void)argc; - - crypt_key_t kl = {0}, kr = {0}; - unsigned char *hl = NULL, *hr = NULL; - unsigned char hlr[CRYPT_HELLO_LEN], hrl[CRYPT_HELLO_LEN]; - unsigned char *nonce = NULL; - net_t nl = {0}, nr = {0}; - crypt_session_t sl = {0}, sr = {0}; - - const int incom_len = 512; - char incom[incom_len]; - int ret = 0; + if (argc < 4) { + usage(); + return -1; + } + if (sodium_init() == -1) { - fprintf(stderr, "A Sodium cryptography library is failed to initialise!\n"); return -1; } // if (audio_init_soundsystem() == -1) // return -1; - if (crypt_key_gen(&kl) == -1) { + char direction = argv[1][0]; + char *addr = argv[2]; + char *port = argv[3]; + + net_t n; + crypt_session_t s; + crypt_key_t ok, rk; + + if (crypt_key_gen(&ok) == -1) { ret = -1; goto cleanup; } - if (crypt_key_gen(&kr) == -1) { - ret = -1; - goto cleanup; - } - - hl = crypt_hello(&kl); - hr = crypt_hello(&kr); - - - if (net_client_init(&nl, "127.0.0.1", "14816") == -1) { - fprintf(stderr, "Failed to intialise a client."); - ret = -1; - goto cleanup; - } - - if (net_server_init(&nr, "127.0.0.1", "14816") == -1) { - fprintf(stderr, "Failed to intialise a server."); - ret = -1; - goto cleanup; - } - - ssize_t sent = net_send(&nl, (const char *)hl, CRYPT_HELLO_LEN); - if (sent == -1) { - ret = -1; - goto cleanup; - } - - ssize_t rcvd = net_recv(&nr, incom, incom_len); - if (rcvd == -1) { - ret = -1; - goto cleanup; - } - - nr.raddr = nr.inaddr; - nr.raddr_len = nr.inaddr_len; - - if (rcvd == CRYPT_HELLO_LEN) { - memcpy(hrl, incom, CRYPT_HELLO_LEN); - } else { - fprintf(stderr, "remote: A broken hello packet was received."); - net_send(&nr, "FUCKOFF", 7); - ret = -1; - goto cleanup; - } - - sent = net_send(&nr, (const char *)hr, CRYPT_HELLO_LEN); - if (sent == -1) { - ret = -1; - goto cleanup; - } - - rcvd = net_recv(&nl, incom, incom_len); - if (rcvd == -1) { - ret = -1; - goto cleanup; - } - - if (rcvd == CRYPT_HELLO_LEN) { - memcpy(hlr, incom, CRYPT_HELLO_LEN); - } else { - if (memcmp("FUCKOFF", incom, 7) == 0) { - fprintf(stderr, "local: A broken hello packet was sent by me."); - } else { - fprintf(stderr, "local: A broken hello packet was received."); - net_send(&nl, "FUCKOFF", 7); + if (direction == 'c') { + if (net_client_init(&n, addr, port) == -1) { + ret = -1; + goto cleanup; } - ret = -1; - goto cleanup; - } + int res = client_handshake(&n, &s, &ok, &rk); - if (crypt_hello_verify(hlr, &kr) == -1) { - fprintf(stderr, "hello remote -> local: not verified\n"); - net_send(&nl, "FUCKOFF", 7); - ret = -1; - goto cleanup; + if (res != 0) { + ret = res; + goto cleanup; + } + } else if (direction == 's') { + if (net_server_init(&n, addr, port) == -1) { + ret = -1; + goto cleanup; + } + + int res = server_handshake(&n, &s, &ok, &rk); + + if (res != 0) { + ret = -1; + goto cleanup; + } } else { - net_send(&nl, "YOU'RE WELCOME", 14); + usage(); } - rcvd = net_recv(&nr, incom, incom_len); - if (rcvd == -1) { - ret = -1; - goto cleanup; - } - - if (crypt_hello_verify(hrl, &kl) == -1) { - fprintf(stderr, "hello local -> remote: not verified\n"); - net_send(&nr, "FUCKOFF", 7); - ret = -1; - goto cleanup; - } else { - net_send(&nr, "YOU'RE WELCOME", 14); - } - - nonce = crypt_hello_get_nonce(hl, hlr, true); - unsigned char *rn = crypt_hello_get_nonce(hr, hrl, false); - - if (memcmp(nonce, rn, CRYPT_NONCE_LEN) != 0) { - fprintf(stderr, "nonce mismatch occured\n"); - free(rn); - ret = -1; - goto cleanup; - } - - free(rn); - - if (crypt_session_init(&sl, &kl, &kr, nonce, true) == -1) { - fprintf(stderr, "local session init fail\n"); - ret = -1; - goto cleanup; - } - - if (crypt_session_init(&sr, &kr, &kl, nonce, false) == -1) { - fprintf(stderr, "remote session init fail\n"); - ret = -1; - goto cleanup; - } - - /* Now we're talking securely! */ - + fprintf(stderr, "A connection established!\n"); cleanup: - net_destroy(&nl); - net_destroy(&nr); - - crypt_key_destroy(&kl); - crypt_key_destroy(&kr); - - crypt_session_destroy(&sl); - crypt_session_destroy(&sr); - - free(hl); - free(hr); - free(nonce); + net_destroy(&n); + crypt_session_destroy(&s); + crypt_key_destroy(&ok); + crypt_key_destroy(&rk); // if (audio_terminate_soundsystem() == -1) // return -1; return ret; } + +int client_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) { + char buffer[NET_BUF_SIZE]; + ssize_t bytes = 0; + unsigned char *hello = NULL; + unsigned char *nonce = NULL; + + if ((hello = crypt_hello(ok)) == NULL) + return -1; + + if (net_send(n, (char *)hello, CRYPT_HELLO_LEN) == -1) { + free(hello); + return -1; + } + + if ((bytes = net_recv(n, buffer, NET_BUF_SIZE)) == -1) { + free(hello); + return -1; + } + + if (CRYPT_HELLO_LEN != bytes) { + free(hello); + return -1; + } + + if (crypt_key_from_hex_public(rk, buffer) == -1) { + free(hello); + return -1; + } + + if (crypt_hello_verify((unsigned char *)buffer, rk) == -1) { + free(hello); + return -2; + } + + if ((nonce = crypt_hello_get_nonce(hello, (unsigned char *)buffer, true)) == NULL) { + free(hello); + return -1; + } + + free(hello); + + if (crypt_session_init(s, ok, rk, nonce, true) == -1) { + free(nonce); + return -3; + } + + free(nonce); + + return 0; +} + +int server_handshake(net_t *const n, crypt_session_t *const s, crypt_key_t *const ok, crypt_key_t *const rk) { + char buffer[NET_BUF_SIZE]; + ssize_t bytes = 0; + unsigned char *hello = NULL; + unsigned char *nonce = NULL; + + if ((bytes = net_recv(n, buffer, NET_BUF_SIZE)) == -1) + return -1; + + if (CRYPT_HELLO_LEN != bytes) + return -1; + + if (crypt_key_from_hex_public(rk, buffer) == -1) + return -1; + + if (crypt_hello_verify((unsigned char *)buffer, rk) == -1) + return -2; + + if ((hello = crypt_hello(ok)) == NULL) + return -1; + + n->raddr = n->inaddr; + n->raddr_len = n->inaddr_len; + + if (net_send(n, (char *)hello, CRYPT_HELLO_LEN) == -1) { + free(hello); + return -1; + } + + if ((nonce = crypt_hello_get_nonce(hello, (unsigned char *)buffer, false)) == NULL) { + free(hello); + return -1; + } + + free(hello); + + if (crypt_session_init(s, ok, rk, nonce, false) == -1) { + free(nonce); + return -3; + } + + free(nonce); + + return 0; +} \ No newline at end of file