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

View Raw

More Information

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

sodiumTest

Log

Files

Refs

README

client4.c (6184B)

     1 #! /usr/bin/env sheepy
     2 
     3 /*
     4 client4 and server4 are following request/response model.
     5 
     6 Steps in client
     7 - load key
     8 - connect to server
     9 - generate nonce
    10 - send command, public key and nonce. Command is the first byte,
    11   0 to request server public key,
    12   1 to send first encrypted message directly
    13 - store remote public key
    14 - send encrypted message
    15 - get encrypted response
    16 
    17 Steps in server
    18 - generate keys
    19 - start event loop
    20 - store remote session public key
    21 - check identity with signature
    22 - send signature, identity public key, session public key, nonce
    23 - get encrypted message
    24 - send encrypted response
    25 
    26 This version uses secret/symetric key encryption after the key exchange.
    27 
    28 For more nonce randomness, the server can provide the first nonce with the public keys when the session opens
    29 
    30 >> when sending large amount of data, use stream functions
    31 >> use aead functions only if there are metadata
    32 >> privelege separation: have a seperate process with the secrets
    33 >> to change id: sign id public key, sign id public key and signature and the new id public key with the new id key
    34 
    35 */
    36 
    37 #include "libsheepyObject.h"
    38 
    39 #include <sys/types.h>
    40 #include <sys/socket.h>
    41 #include <netdb.h>
    42 #include <netinet/in.h>
    43 
    44 #include "sel.h"
    45 
    46 int main(int ac, char **av) {
    47 
    48   setLogMode(LOG_FUNC);
    49 
    50   if (not selInit()) ret 1;
    51 
    52   // generate keys
    53   bool isKnownServer                      = no;
    54   const char* clientSecretFilename        = "client4Secret.bin";
    55   const char* clientPublicFilename        = "client4Public.bin";
    56   bool sendClientIdToServer               = yes;
    57 
    58   // load client key if possible
    59   if (isPath(clientPublicFilename)) {
    60     logI("Client already has a session key");
    61     pError0(bLReadFile(clientSecretFilename, keys.secretKey, sizeof(keys.secretKey)));
    62     pError0(bLReadFile(clientPublicFilename, keys.publicKey, sizeof(keys.publicKey)));
    63   }
    64   else {
    65     newKeys();
    66     pError0(writeFile(clientSecretFilename, keys.secretKey, sizeof(keys.secretKey)));
    67     pError0(writeFile(clientPublicFilename, keys.publicKey, sizeof(keys.publicKey)));
    68   }
    69   newSignKeys();
    70 
    71         char *msg = "Hello";
    72 
    73         logI("message: %s\n", msg);
    74 
    75 
    76   // connect to server
    77   int sock;
    78   struct sockaddr_in server;
    79   struct hostent *hp;
    80   int mysock;
    81   char buf[128*1024];
    82   int rval;
    83 
    84   void connectToServer(void) {
    85     sock = socket(AF_INET, SOCK_STREAM, 0);
    86     if (sock < 0){
    87       perror("Failed to create socket");
    88     }
    89 
    90     server.sin_family = AF_INET;
    91 
    92     hp = gethostbyname(av[1]);
    93     if (hp==0) {
    94       perror("gethostbyname failed");
    95       close(sock);
    96       exit(1);
    97     }
    98 
    99     memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
   100     server.sin_port = htons(5000);
   101 
   102     if (connect(sock,(struct sockaddr *) &server, sizeof(server))){
   103       perror("connect failed");
   104       close(sock);
   105       exit(1);
   106     }
   107   }
   108   connectToServer();
   109 
   110   void snd(void *buf, size_t sz) {
   111     logVarG(sz);
   112     if(send(sock, buf, sz, 0) < 0){
   113       perror("send failed");
   114       close(sock);
   115       exit(1);
   116     }
   117   }
   118 
   119   void rcv(void *buf, size_t sz) {
   120     while (sz > 0) {
   121       rval = recv(sock, buf, sz, MSG_WAITALL);
   122       if (rval < 0) {
   123         perror("reading message");
   124         exit(1);
   125       }
   126       else if (rval == 0) {
   127         logI("Ending connection");
   128         close(sock);
   129         exit(0);
   130       }
   131       sz -= rval;
   132     }
   133     logVarG(rval);
   134   }
   135 
   136   // send public key
   137   // store remote public key
   138   void getServerPublicKey(void) {
   139           randombytes_buf(keys.nonce, sizeof(keys.nonce));
   140     u8 exchange[1 + sizeof(keys.publicKey) + sizeof(keys.nonce)] = init0Var;
   141     memcpy(exchange + 1, &keys.publicKey, sizeof(keys.publicKey));
   142     memcpy(exchange + 1 + sizeof(keys.publicKey), &keys.nonce, sizeof(keys.nonce));
   143     snd(exchange, sizeof(exchange));
   144 
   145     u8 serverInfo[sizeof(keys.remotePublicKey)] = init0Var;
   146     rcv(serverInfo, sizeof(serverInfo));
   147 
   148     memcpy(keys.remotePublicKey, serverInfo, sizeof(keys.remotePublicKey));
   149 
   150     logD("Remote public key");
   151     loghex(keys.remotePublicKey, sizeof(keys.remotePublicKey));
   152     put;
   153 
   154     // key exchange
   155     if (not computeSharedKeys(CLIENT_SESSION_KEYS)) {
   156       logE("Invalid server key");
   157       exit(1);
   158     }
   159   }
   160 
   161   getServerPublicKey();
   162 
   163   // send encrypted message
   164   // *nonce is incremented by after sending or receiving a message
   165   // *nonce is allowed to wrap from the max value
   166   u64 *nonce = (u64*)keys.nonce;
   167   logVarG(*nonce);
   168   int len = selEncrypt(buf, sizeof(buf), msg, strlen(msg));
   169   inc *nonce;
   170 
   171   logVarG(len);
   172 
   173   snd(&len, sizeof(len));
   174   snd(buf, len);
   175 
   176   // get encrypted response
   177   rcv(&len, sizeof(len));
   178   rcv(buf, len);
   179 
   180         u8 decrypted[1000];
   181   logVarG(*nonce);
   182   len = selDecrypt(decrypted, sizeof(decrypted), buf, len);
   183   inc *nonce;
   184 
   185   if (!len) {
   186     logE("failed to decrypt");
   187     ret 1;
   188   }
   189 
   190   decrypted[len] = 0;
   191 
   192   logI("decrypted: %s", decrypted);
   193 
   194   close(sock);
   195 
   196 
   197   //////////////////////////////////////////
   198   // second session, server public is known
   199   {
   200   msg = "Second client session";
   201   connectToServer();
   202 
   203   // send public key
   204         randombytes_buf(keys.nonce, sizeof(keys.nonce));
   205   u8 exchange[1 + sizeof(keys.publicKey) + sizeof(keys.nonce)] = init0Var;
   206   // command 1 send encrypted message directly
   207   exchange[0] = 1;
   208   memcpy(exchange + 1, &keys.publicKey, sizeof(keys.publicKey));
   209   memcpy(exchange + 1 + sizeof(keys.publicKey), &keys.nonce, sizeof(keys.nonce));
   210   snd(exchange, sizeof(exchange));
   211 
   212   // key exchange
   213   if (not computeSharedKeys(CLIENT_SESSION_KEYS)) {
   214     logE("Invalid server key");
   215     exit(1);
   216   }
   217 
   218   // send encrypted message
   219   // *nonce is incremented by after sending or receiving a message
   220   // *nonce is allowed to wrap from the max value
   221   u64 *nonce = (u64*)keys.nonce;
   222   logVarG(*nonce);
   223   int len = selEncrypt(buf, sizeof(buf), msg, strlen(msg));
   224   inc *nonce;
   225 
   226   logVarG(len);
   227 
   228   snd(&len, sizeof(len));
   229   snd(buf, len);
   230 
   231   // get encrypted response
   232   rcv(&len, sizeof(len));
   233   rcv(buf, len);
   234 
   235         u8 decrypted[1000];
   236   logVarG(*nonce);
   237   len = selDecrypt(decrypted, sizeof(decrypted), buf, len);
   238   inc *nonce;
   239 
   240   if (!len) {
   241     logE("failed to decrypt");
   242     ret 1;
   243   }
   244 
   245   decrypted[len] = 0;
   246 
   247   logI("decrypted: %s", decrypted);
   248 
   249   close(sock);
   250   }
   251 
   252 }
   253 // vim: set expandtab ts=2 sw=2: