1
0

A proper handshake was implemented.

This commit is contained in:
Alexander Andreev 2024-03-26 04:51:31 +04:00
parent ccca06e70f
commit b06d955f98
Signed by: Arav
GPG Key ID: 25969B23DCB5CA34

View File

@ -1,5 +1,6 @@
#include <portaudio.h> #include <portaudio.h>
#include <sodium/core.h> #include <sodium/core.h>
#include <sodium/crypto_box.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -12,177 +13,187 @@
#define CHANNELS 1 #define CHANNELS 1
#define SAMPLE_RATE 48000 #define SAMPLE_RATE 48000
#define FRAMES_PER_BUFFFER 960 #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) { 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; int ret = 0;
if (argc < 4) {
usage();
return -1;
}
if (sodium_init() == -1) { if (sodium_init() == -1) {
fprintf(stderr, "A Sodium cryptography library is failed to initialise!\n");
return -1; return -1;
} }
// if (audio_init_soundsystem() == -1) // if (audio_init_soundsystem() == -1)
// return -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; ret = -1;
goto cleanup; goto cleanup;
} }
if (crypt_key_gen(&kr) == -1) { if (direction == 'c') {
if (net_client_init(&n, addr, port) == -1) {
ret = -1; ret = -1;
goto cleanup; goto cleanup;
} }
hl = crypt_hello(&kl); int res = client_handshake(&n, &s, &ok, &rk);
hr = crypt_hello(&kr);
if (res != 0) {
if (net_client_init(&nl, "127.0.0.1", "14816") == -1) { ret = res;
fprintf(stderr, "Failed to intialise a client."); goto cleanup;
}
} else if (direction == 's') {
if (net_server_init(&n, addr, port) == -1) {
ret = -1; ret = -1;
goto cleanup; goto cleanup;
} }
if (net_server_init(&nr, "127.0.0.1", "14816") == -1) { int res = server_handshake(&n, &s, &ok, &rk);
fprintf(stderr, "Failed to intialise a server.");
if (res != 0) {
ret = -1; ret = -1;
goto cleanup; 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 { } else {
fprintf(stderr, "remote: A broken hello packet was received."); usage();
net_send(&nr, "FUCKOFF", 7);
ret = -1;
goto cleanup;
} }
sent = net_send(&nr, (const char *)hr, CRYPT_HELLO_LEN); fprintf(stderr, "A connection established!\n");
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);
}
ret = -1;
goto cleanup;
}
if (crypt_hello_verify(hlr, &kr) == -1) {
fprintf(stderr, "hello remote -> local: not verified\n");
net_send(&nl, "FUCKOFF", 7);
ret = -1;
goto cleanup;
} else {
net_send(&nl, "YOU'RE WELCOME", 14);
}
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! */
cleanup: cleanup:
net_destroy(&nl); net_destroy(&n);
net_destroy(&nr); crypt_session_destroy(&s);
crypt_key_destroy(&ok);
crypt_key_destroy(&kl); crypt_key_destroy(&rk);
crypt_key_destroy(&kr);
crypt_session_destroy(&sl);
crypt_session_destroy(&sr);
free(hl);
free(hr);
free(nonce);
// if (audio_terminate_soundsystem() == -1) // if (audio_terminate_soundsystem() == -1)
// return -1; // return -1;
return ret; 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;
}