💾 Archived View for gmi.noulin.net › gitRepositories › sodiumTest › file › presharedClientudp.c.gmi captured on 2024-08-25 at 09:13:35. Gemini links have been rewritten to link to archived content

View Raw

More Information

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

sodiumTest

Log

Files

Refs

README

presharedClientudp.c (3971B)

     1 #! /usr/bin/env sheepy
     2 
     3 /*
     4 client sends data to server. Client doesn't get any responses from the server
     5 The keys are preshared, there is no key exchange.
     6 
     7 The client knows: client secret key, client public key and server public key
     8 The server knows: client public key, server secret key and server public key
     9 
    10 Run this to generate the client and server keys:
    11 
    12 ./presharedClient.c generate keys
    13 
    14 The messages don't need to be signed because the client uses the client secret and
    15 the server public keys to encrypt.
    16 
    17 Steps in client
    18 - load keys
    19 - connect to server
    20 - send encrypted message
    21 
    22 Steps in server
    23 - start event loop
    24 - get encrypted message
    25 
    26 It uses public key encryption which is slow compare to secret/symetric key encryption
    27 Secret key encryption is between 25 and 50 times faster than public key encryption depending on the CPU.
    28 With secret key encryption, my computer can encode 4GB/s which is enough (I have 1GB/s network).
    29 
    30 The nonces are not verified, each nonce can be used multiple times, so replay attacks would be successful.
    31 */
    32 
    33 #include "libsheepyObject.h"
    34 
    35 #include <sys/types.h>
    36 #include <sys/socket.h>
    37 #include <netdb.h>
    38 #include <netinet/in.h>
    39 
    40 #include "sel.h"
    41 
    42 int main(int ac, char **av) {
    43 
    44   setLogMode(LOG_FUNC);
    45 
    46   if (not selInit()) ret 1;
    47 
    48   const char* clientSecretFilename = "presharedClientSecret.bin";
    49   const char* clientPublicFilename = "presharedClientPublic.bin";
    50   const char* serverSecretFilename = "presharedServerSecret.bin";
    51   const char* serverPublicFilename = "presharedServerPublic.bin";
    52   keyst clientKeys                 = init0Var;
    53   keyst serverKeys                 = init0Var;
    54 
    55   if (ac > 2) {
    56     // generate keys
    57     logI("Generate keys");
    58     newKeysBuf(&clientKeys);
    59     newKeysBuf(&serverKeys);
    60     pError0(writeFile(clientSecretFilename, clientKeys.secretKey, sizeof(clientKeys.secretKey)));
    61     pError0(writeFile(clientPublicFilename, clientKeys.publicKey, sizeof(clientKeys.publicKey)));
    62     pError0(writeFile(serverSecretFilename, serverKeys.secretKey, sizeof(serverKeys.secretKey)));
    63     pError0(writeFile(serverPublicFilename, serverKeys.publicKey, sizeof(serverKeys.publicKey)));
    64     ret 0;
    65   }
    66 
    67   // load keys
    68   pError0(bLReadFile(clientSecretFilename, clientKeys.secretKey, sizeof(clientKeys.secretKey)));
    69   pError0(bLReadFile(clientPublicFilename, clientKeys.publicKey, sizeof(clientKeys.publicKey)));
    70   pError0(bLReadFile(serverPublicFilename, clientKeys.remotePublicKey, sizeof(clientKeys.remotePublicKey)));
    71 
    72         char *msg = "Hello";
    73 
    74         logI("message: %s\n", msg);
    75 
    76 
    77   // connect to server
    78   int sock;
    79   struct sockaddr_in server;
    80   struct hostent *hp;
    81   typ struct PACKED {
    82     u64 time;
    83     char buf[64*1024];
    84   } payloadt;
    85   typ struct PACKED {
    86     u8 nonce[crypto_box_NONCEBYTES];
    87     i32 len;
    88     payloadt payload;
    89   } packett;
    90   packett data = init0Var;
    91   int rval;
    92 
    93   sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    94   if (sock < 0){
    95     perror("Failed to create socket");
    96   }
    97 
    98   server.sin_family = AF_INET;
    99 
   100   hp = gethostbyname(av[1]);
   101   if (hp==0) {
   102     perror("gethostbyname failed");
   103     close(sock);
   104     exit(1);
   105   }
   106 
   107   memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
   108   server.sin_port = htons(5000);
   109 
   110   // send encrypted message with nonce
   111         randombytes_buf(clientKeys.nonce, sizeof(clientKeys.nonce));
   112   memcpy(data.nonce, clientKeys.nonce, sizeof(clientKeys.nonce));
   113   payloadt payload;
   114   // set timestamp in encrypted message to avoid replay attacks
   115   payload.time = getCurrentUnixTime() /*- 2 */; // uncomment to introduce an error
   116   memcpy(payload.buf, msg, strlen(msg));
   117   data.len = selPublicEncrypt((u8*)&data.payload, sizeof(data.payload), (u8*)&payload, sizeof(payload.time) + strlen(msg), &clientKeys);
   118 
   119   logVarG(data.len);
   120 
   121   if (sendto(sock, &data, data.len + sizeof(data.len) + sizeof(data.nonce), 0, (const struct sockaddr *)&server, sizeof(server)) < 0) {
   122     perror("send failed");
   123     close(sock);
   124     exit(1);
   125   }
   126 
   127   close(sock);
   128 }
   129 // vim: set expandtab ts=2 sw=2: