zsm/src/client/client.c

148 lines
3.8 KiB
C
Raw Normal View History

2024-04-30 18:17:17 +02:00
#include "packet.h"
#include <pthread.h>
uint8_t shared_key[SHARED_KEY_SIZE];
int sockfd;
/*
* Connect to socket server
*/
int socket_init()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error(1, "Error on opening socket");
}
struct hostent *server = gethostbyname(DOMAIN);
if (server == NULL) {
error(1, "No such host %s", DOMAIN);
}
struct sockaddr_in sv_addr;
memset(&sv_addr, 0, sizeof(sv_addr));
sv_addr.sin_family = AF_INET;
sv_addr.sin_port = htons(PORT);
memcpy(&sv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
/* free(server); */
if (connect(sockfd, (struct sockaddr *) &sv_addr, sizeof(sv_addr)) < 0) {
error(1, "Error on connect");
close(sockfd);
return 0;
}
printf("Connected to server at %s\n", DOMAIN);
return sockfd;
}
/*
* Performs key exchange with server
*/
int key_exchange(int sockfd)
{
/* Generate the client's key pair */
uint8_t cl_pk[PUBLIC_KEY_SIZE], cl_sk[PRIVATE_KEY_SIZE];
crypto_kx_keypair(cl_pk, cl_sk);
/* Send our public key */
if (send_public_key(sockfd, cl_pk) < 0) {
return -1;
}
/* Get public key from server */
uint8_t *pk;
if ((pk = get_public_key(sockfd)) == NULL) {
return -1;
}
/* Compute a shared key using the server's public key and our secret key */
if (crypto_kx_client_session_keys(NULL, shared_key, cl_pk, cl_sk, pk) != 0) {
error(1, "Server public key is not acceptable");
free(pk);
close(sockfd);
return -1;
}
free(pk);
return 0;
}
void *sender()
{
while (1) {
printf("Enter message to send to server: ");
fflush(stdout);
char line[1024];
line[0] = '\0';
size_t length = strlen(line);
while (length <= 1) {
fgets(line, sizeof(line), stdin);
length = strlen(line);
}
length -= 1;
line[length] = '\0';
uint8_t nonce[NONCE_SIZE];
uint8_t encrypted[length + ADDITIONAL_SIZE];
unsigned long long encrypted_len;
randombytes_buf(nonce, sizeof(nonce));
crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_len,
line, length,
NULL, 0, NULL, nonce, shared_key);
size_t payload_t = NONCE_SIZE + encrypted_len;
uint8_t encryptedwithnonce[payload_t];
memcpy(encryptedwithnonce, nonce, NONCE_SIZE);
memcpy(encryptedwithnonce + NONCE_SIZE, encrypted, encrypted_len);
message *msg = create_packet(1, 0x10, payload_t, encryptedwithnonce);
if (send_packet(msg, sockfd) != ZSM_STA_SUCCESS) {
close(sockfd);
}
free_packet(msg);
}
close(sockfd);
}
void *receiver()
{
while (1) {
message servermsg;
if (recv_packet(&servermsg, sockfd) != ZSM_STA_SUCCESS) {
close(sockfd);
return 0;
}
free(servermsg.data);
}
return NULL;
}
int main()
{
if (sodium_init() < 0) {
error(1, "Error initializing libsodium");
}
sockfd = socket_init();
if (key_exchange(sockfd) < 0) {
/* Fatal */
error(1, "Error performing key exchange with server");
}
pthread_t recv_worker, send_worker;
if (pthread_create(&recv_worker, NULL, sender, NULL) != 0) {
fprintf(stderr, "Error creating incoming thread\n");
return 1;
}
if (pthread_create(&send_worker, NULL, receiver, NULL) != 0) {
fprintf(stderr, "Error creating outgoing thread\n");
return 1;
}
// Join threads
pthread_join(recv_worker, NULL);
pthread_join(send_worker, NULL);
return 0;
}