💾 Archived View for gmi.noulin.net › gitRepositories › sodiumTest › file › server2.c.gmi captured on 2023-07-10 at 18:15:04. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

sodiumTest

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: