💾 Archived View for gmi.noulin.net › gitRepositories › sodiumTest › file › client.c.gmi captured on 2023-01-29 at 13:28:10. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2024-07-09)

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

sodiumTest

Log

Files

Refs

README

client.c (3684B)

     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   newKeys(&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: