zsm

Zen Secure Messaging
git clone https://codeberg.org/night0721/zsm
Log | Files | Refs | README | LICENSE

client.c (3849B)


      1 #include "packet.h"
      2 #include <pthread.h>
      3 
      4 uint8_t shared_key[SHARED_KEY_SIZE];
      5 int sockfd;
      6 
      7 /*
      8  * Connect to socket server
      9  */
     10 int socket_init()
     11 {
     12     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
     13     if (sockfd < 0) {
     14         error(1, "Error on opening socket");
     15     }
     16 
     17     struct hostent *server = gethostbyname(DOMAIN);
     18     if (server == NULL) {
     19         error(1, "No such host %s", DOMAIN);
     20     }
     21 
     22     struct sockaddr_in sv_addr;
     23     memset(&sv_addr, 0, sizeof(sv_addr));
     24     sv_addr.sin_family = AF_INET;
     25     sv_addr.sin_port = htons(PORT);
     26     memcpy(&sv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
     27 
     28 /*     free(server); */
     29     if (connect(sockfd, (struct sockaddr *) &sv_addr, sizeof(sv_addr)) < 0) {
     30         error(1, "Error on connect");
     31         close(sockfd);
     32         return 0;
     33     }
     34     printf("Connected to server at %s\n", DOMAIN);
     35     return sockfd;
     36 }
     37 
     38 /*
     39  * Performs key exchange with server
     40  */
     41 int key_exchange(int sockfd)
     42 {
     43     /* Generate the client's key pair */
     44     uint8_t cl_pk[PUBLIC_KEY_SIZE], cl_sk[PRIVATE_KEY_SIZE];
     45     crypto_kx_keypair(cl_pk, cl_sk);
     46 
     47     /* Send our public key */
     48     if (send_public_key(sockfd, cl_pk) < 0) {
     49         return -1;
     50     }
     51     
     52     /* Get public key from server */
     53     uint8_t *pk;
     54     if ((pk = get_public_key(sockfd)) == NULL) {
     55         return -1;
     56     }
     57 
     58     /* Compute a shared key using the server's public key and our secret key */
     59     if (crypto_kx_client_session_keys(NULL, shared_key, cl_pk, cl_sk, pk) != 0) {
     60         error(1, "Server public key is not acceptable");
     61         free(pk);
     62         close(sockfd);
     63         return -1;
     64     }
     65     free(pk);
     66     return 0;
     67 }
     68 
     69 void *sender()
     70 {
     71     while (1) {
     72         printf("Enter message to send to server: ");
     73         fflush(stdout);
     74         char line[1024];
     75         line[0] = '\0';
     76         size_t length = strlen(line);
     77         while (length <= 1) {
     78             fgets(line, sizeof(line), stdin);
     79             length = strlen(line);
     80         }
     81         length -= 1;
     82         line[length] = '\0';
     83 
     84         uint8_t nonce[NONCE_SIZE];
     85         uint8_t encrypted[length + ADDITIONAL_SIZE];
     86         unsigned long long encrypted_len;
     87         
     88         randombytes_buf(nonce, sizeof(nonce));
     89         crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_len,
     90                                                    line, length,
     91                                                    NULL, 0, NULL, nonce, shared_key);
     92         size_t payload_t = NONCE_SIZE + encrypted_len; 
     93         uint8_t encryptedwithnonce[payload_t];
     94         memcpy(encryptedwithnonce, nonce, NONCE_SIZE);
     95         memcpy(encryptedwithnonce + NONCE_SIZE, encrypted, encrypted_len);
     96         
     97         message *msg = create_packet(1, 0x10, payload_t, encryptedwithnonce);
     98         if (send_packet(msg, sockfd) != ZSM_STA_SUCCESS) {
     99             close(sockfd);
    100         }
    101         free_packet(msg);
    102     }
    103     close(sockfd);
    104 
    105 }
    106 
    107 void *receiver()
    108 {
    109     while (1) {
    110         message servermsg;
    111         if (recv_packet(&servermsg, sockfd) != ZSM_STA_SUCCESS) {
    112             close(sockfd);
    113             return 0;
    114         }
    115         free(servermsg.data);
    116     }
    117     return NULL;
    118 }
    119 
    120 int main()
    121 {
    122     if (sodium_init() < 0) {
    123         error(1, "Error initializing libsodium");
    124     }
    125     sockfd = socket_init();
    126     if (key_exchange(sockfd) < 0) {
    127         /* Fatal */
    128         error(1, "Error performing key exchange with server");
    129     }
    130     pthread_t recv_worker, send_worker;
    131     if (pthread_create(&recv_worker, NULL, sender, NULL) != 0) {
    132         fprintf(stderr, "Error creating incoming thread\n");
    133         return 1;
    134     }
    135 
    136     if (pthread_create(&send_worker, NULL, receiver, NULL) != 0) {
    137         fprintf(stderr, "Error creating outgoing thread\n");
    138         return 1;
    139     }
    140 
    141     // Join threads
    142     pthread_join(recv_worker, NULL);
    143     pthread_join(send_worker, NULL);
    144 
    145     return 0;
    146 }
    147