💾 Archived View for gmi.noulin.net › gitRepositories › sodiumTest › file › server3.c.gmi captured on 2024-07-09 at 02:45:42. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

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

sodiumTest

Log

Files

Refs

README

server3.c (5423B)

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