sodiumTest

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

server2.c (4577B)


      1 #! /usr/bin/env sheepy
      2 
      3 #include "libsheepyObject.h"
      4 
      5 #include <sys/socket.h>
      6 #include <netinet/in.h>
      7 
      8 #include "sel.h"
      9 
     10 int main(int ac, char **av){
     11 
     12   setLogMode(LOG_FUNC);
     13 
     14   if (not selInit()) ret 1;
     15 
     16   // generate id keys
     17   newSignKeys();
     18 
     19 
     20   // start event loop
     21   int sock;
     22   struct sockaddr_in server;
     23   int mysock;
     24   char buf[128*1024];
     25   int rval;
     26 
     27   sock = socket(AF_INET, SOCK_STREAM, 0);
     28   if (sock < 0){
     29     perror("Failed to create socket");
     30     ret 1;
     31   }
     32 
     33   server.sin_family = AF_INET;
     34   server.sin_addr.s_addr = INADDR_ANY;
     35   server.sin_port = htons(5000);
     36 
     37   if (bind(sock, (struct sockaddr *) &server, sizeof(server))){
     38     perror("bind failed");
     39     ret 1;
     40   }
     41 
     42   listen(sock, 5);
     43 
     44   logI("Server started");
     45   forever {
     46     mysock = accept(sock, (struct sockaddr *)0, 0);
     47     if (mysock == -1)
     48       perror("accept failed");
     49     else {
     50 
     51       bool snd(void *buf, size_t sz) {
     52         logVarG(sz);
     53         if(send(mysock, buf, sz, 0) < 0){
     54           perror("send failed");
     55           close(mysock);
     56           ret no;
     57         }
     58         ret yes;
     59       }
     60 
     61       bool rcv(void *buf, size_t sz) {
     62         while (sz > 0) {
     63           // TODO add timeout
     64           rval = recv(mysock, buf, sz, MSG_WAITALL);
     65           if (rval < 0) {
     66             perror("reading message");
     67             ret no;
     68           }
     69           else if (rval == 0) {
     70             logI("Ending connection");
     71             close(mysock);
     72             ret no;
     73           }
     74           sz -= rval;
     75         }
     76         ret yes;
     77       }
     78 
     79       // public key for session
     80       newKeys();
     81 	    randombytes_buf(sessionKeys.nonce, sizeof(sessionKeys.nonce));
     82 
     83       // store remote public key
     84       u8 clientInfo[crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES + sizeof(keys.remotePublicKey)] = init0Var;
     85       rcv(clientInfo, sizeof(clientInfo));
     86 
     87       // check if the clientInfo is signed
     88       bool is0 = yes;
     89       range(i, crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES) {
     90         if (clientInfo[i]) {
     91           is0 = no;
     92           break;
     93         }
     94       }
     95 
     96       if (is0) {
     97         logN("Client id not checked");
     98       }
     99       else {
    100         // check client
    101         // id key should already be known
    102         u8 unsigned_message[crypto_sign_PUBLICKEYBYTES + sizeof(keys.remotePublicKey)] = init0Var;
    103         unsigned long long unsigned_message_len;
    104 
    105         if (crypto_sign_open(unsigned_message, &unsigned_message_len, clientInfo, sizeof(clientInfo), clientInfo + crypto_sign_BYTES) != 0) {
    106           logE("Incorrect signature!");
    107         }
    108         else {
    109           logP("Correct client signature");
    110         }
    111       }
    112 
    113       memcpy(keys.remotePublicKey, clientInfo + crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES, sizeof(keys.remotePublicKey));
    114 
    115       logD("Remote public key");
    116       loghex(keys.remotePublicKey, sizeof(keys.remotePublicKey));
    117       put;
    118 
    119       // send public key
    120       u8 exchange[crypto_sign_PUBLICKEYBYTES + sizeof(keys.publicKey) + crypto_box_NONCEBYTES] = init0Var;
    121       u8 signed_message[crypto_sign_BYTES + sizeof(exchange)] = init0Var;
    122       unsigned long long signed_message_len = 0;
    123 
    124       memcpy(exchange, identityKeys.publicKey, crypto_sign_PUBLICKEYBYTES);
    125       memcpy(exchange + crypto_sign_PUBLICKEYBYTES, keys.publicKey, sizeof(keys.publicKey));
    126       memcpy(exchange + crypto_sign_PUBLICKEYBYTES + sizeof(keys.publicKey), sessionKeys.nonce, sizeof(sessionKeys.nonce));
    127 
    128       crypto_sign(signed_message, &signed_message_len, exchange, sizeof(exchange), identityKeys.secretKey);
    129 
    130       if (!snd(signed_message, sizeof(signed_message))) continue;
    131 
    132       // key exchange
    133       if (not computeSharedKeys(SERVER_SESSION_KEYS)) {
    134         logE("Invalid client key");
    135         exit(1);
    136       }
    137 
    138       // get encrypted message
    139       int len;
    140       // *nonce is incremented by after sending or receiving a message
    141       // *nonce is allowed to wrap from the max value
    142       u64 *nonce = (u64*)sessionKeys.nonce;
    143       if (!rcv(&len, sizeof(len))) continue;
    144       rcv(buf, len);
    145 
    146       u8 decrypted[1000];
    147       logVarG(*nonce);
    148       len = selDecrypt(decrypted, sizeof(decrypted), buf, len);
    149       inc *nonce;
    150 
    151       if (!len) {
    152         logE("failed to decrypt");
    153         close(mysock);
    154         continue;
    155       }
    156 
    157       decrypted[len] = 0;
    158 
    159       logI("decrypted: %s", decrypted);
    160 
    161       // send encrypted response
    162 
    163       char *msg = "OK";
    164 
    165       logVarG(*nonce);
    166       len = selEncrypt(buf, sizeof(buf), msg, strlen(msg));
    167       inc *nonce;
    168 
    169       logVarG(len);
    170 
    171       snd(&len, sizeof(len));
    172       snd(buf, len);
    173 
    174       close(mysock);
    175     }
    176   }
    177 }
    178 // vim: set expandtab ts=2 sw=2: