💾 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
-=-=-=-=-=-=-
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: