sodiumTest

Libsodium examples, client/server system
git clone https://noulin.net/git/sodiumTest.git
Log | Files | Refs | README

client.c (3687B)


      1 #! /usr/bin/env sheepy
      2 
      3 /*
      4 client and server are following request/response model.
      5 
      6 Steps in client
      7 - generate keys
      8 - connect to server
      9 - send public key
     10 - store remote public key
     11 - send encrypted message
     12 - get encrypted response
     13 
     14 Steps in server
     15 - generate keys
     16 - start event loop
     17 - store remote public key
     18 - send public key
     19 - get encrypted message
     20 - send encrypted response
     21 
     22 It uses public key encryption which is slow compare to secret/symetric key encryption
     23 Secret key encryption is between 25 and 50 times faster than public key encryption depending on the CPU.
     24 With secret key encryption, my computer can encode 4GB/s which is enough (I have 1GB/s network).
     25 
     26 The client and server don't have identities, the client can't verify the server and the server can't verify the client
     27 
     28 The nonces are not verified, each nonce can be used multiple times, so replay attacks would be successful.
     29 */
     30 
     31 #include "libsheepyObject.h"
     32 
     33 #include <sys/types.h>
     34 #include <sys/socket.h>
     35 #include <netdb.h>
     36 #include <netinet/in.h>
     37 
     38 #include "sel.h"
     39 
     40 int main(int ac, char **av) {
     41 
     42   setLogMode(LOG_FUNC);
     43 
     44   if (not selInit()) ret 1;
     45 
     46   // generate keys
     47   keyst clientKeys = init0Var;
     48 
     49   newKeysBuf(&clientKeys);
     50 
     51 	char *msg = "Hello";
     52 
     53 	logI("message: %s\n", msg);
     54 
     55 
     56   // connect to server
     57   int sock;
     58   struct sockaddr_in server;
     59   struct hostent *hp;
     60   int mysock;
     61   char buf[128*1024];
     62   int rval;
     63 
     64   sock = socket(AF_INET, SOCK_STREAM, 0);
     65   if (sock < 0){
     66     perror("Failed to create socket");
     67   }
     68 
     69   server.sin_family = AF_INET;
     70 
     71   hp = gethostbyname(av[1]);
     72   if (hp==0) {
     73     perror("gethostbyname failed");
     74     close(sock);
     75     exit(1);
     76   }
     77 
     78   memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
     79   server.sin_port = htons(5000);
     80 
     81   if (connect(sock,(struct sockaddr *) &server, sizeof(server))){
     82     perror("connect failed");
     83     close(sock);
     84     exit(1);
     85   }
     86 
     87   void snd(void *buf, size_t sz) {
     88     logVarG(sz);
     89     if(send(sock, buf, sz, 0) < 0){
     90       perror("send failed");
     91       close(sock);
     92       exit(1);
     93     }
     94   }
     95 
     96   void rcv(void *buf, size_t sz) {
     97     rval = recv(sock, buf, sizeof(buf), 0);
     98     if (rval < 0) {
     99       perror("reading message");
    100       exit(1);
    101     }
    102     else if (rval == 0) {
    103       logI("Ending connection");
    104       close(sock);
    105       exit(0);
    106     }
    107     logVarG(rval);
    108   }
    109 
    110   // send public key
    111   // store remote public key
    112   void getServerPublicKey(void) {
    113     snd(&clientKeys.publicKey, sizeof(clientKeys.publicKey));
    114     rval = recv(sock, &clientKeys.remotePublicKey, sizeof(clientKeys.remotePublicKey), MSG_WAITALL);
    115     if (rval < 0) {
    116       perror("reading message");
    117       exit(1);
    118     }
    119     else if (rval == 0) {
    120       logI("Ending connection");
    121       close(sock);
    122       exit(0);
    123     }
    124     logVarG(rval);
    125 
    126     logD("Remote public key");
    127     loghex(clientKeys.remotePublicKey, sizeof(clientKeys.remotePublicKey));
    128     put;
    129   }
    130 
    131   getServerPublicKey();
    132 
    133   // send encrypted message
    134 	//randombytes_buf(clientKeys.nonce, sizeof(clientKeys.nonce));
    135   int len = selPublicEncrypt(buf, sizeof(buf), msg, strlen(msg), &clientKeys);
    136 
    137   logVarG(len);
    138 
    139   snd(&len, sizeof(len));
    140   snd(buf, len);
    141 
    142   // get encrypted response
    143   rcv(&len, sizeof(len));
    144   rval = recv(sock, buf, len, MSG_WAITALL);
    145   if (rval < 0) {
    146     perror("reading message");
    147     exit(1);
    148   }
    149   else if (rval == 0) {
    150     logI("Ending connection");
    151     close(sock);
    152     exit(0);
    153   }
    154   logVarG(rval);
    155 
    156   clientKeys.nonce[0] = 1;
    157 
    158 	u8 decrypted[1000];
    159   len = selPublicDecrypt(decrypted, sizeof(decrypted), buf, rval, &clientKeys);
    160 
    161   if (!len) {
    162     logE("failed to decrypt");
    163     ret 1;
    164   }
    165 
    166   decrypted[len] = 0;
    167 
    168   logI("decrypted: %s", decrypted);
    169 
    170   close(sock);
    171 }
    172 // vim: set expandtab ts=2 sw=2: