💾 Archived View for gmi.noulin.net › gitRepositories › sodiumTest › file › server2.c.gmi captured on 2024-07-09 at 02:45:38. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
server2.c (4577B)
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 10 int main(int ac, char **av){ 11 12 setLogMode(LOG_FUNC); 13 14 if (not selInit()) ret 1; 15 16 // generate id keys 17 newSignKeys(); 18 19 20 // start event loop 21 int sock; 22 struct sockaddr_in server; 23 int mysock; 24 char buf[128*1024]; 25 int rval; 26 27 sock = socket(AF_INET, SOCK_STREAM, 0); 28 if (sock < 0){ 29 perror("Failed to create socket"); 30 ret 1; 31 } 32 33 server.sin_family = AF_INET; 34 server.sin_addr.s_addr = INADDR_ANY; 35 server.sin_port = htons(5000); 36 37 if (bind(sock, (struct sockaddr *) &server, sizeof(server))){ 38 perror("bind failed"); 39 ret 1; 40 } 41 42 listen(sock, 5); 43 44 logI("Server started"); 45 forever { 46 mysock = accept(sock, (struct sockaddr *)0, 0); 47 if (mysock == -1) 48 perror("accept failed"); 49 else { 50 51 bool snd(void *buf, size_t sz) { 52 logVarG(sz); 53 if(send(mysock, buf, sz, 0) < 0){ 54 perror("send failed"); 55 close(mysock); 56 ret no; 57 } 58 ret yes; 59 } 60 61 bool rcv(void *buf, size_t sz) { 62 while (sz > 0) { 63 // TODO add timeout 64 rval = recv(mysock, buf, sz, MSG_WAITALL); 65 if (rval < 0) { 66 perror("reading message"); 67 ret no; 68 } 69 else if (rval == 0) { 70 logI("Ending connection"); 71 close(mysock); 72 ret no; 73 } 74 sz -= rval; 75 } 76 ret yes; 77 } 78 79 // public key for session 80 newKeys(); 81 randombytes_buf(sessionKeys.nonce, sizeof(sessionKeys.nonce)); 82 83 // store remote public key 84 u8 clientInfo[crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES + sizeof(keys.remotePublicKey)] = init0Var; 85 rcv(clientInfo, sizeof(clientInfo)); 86 87 // check if the clientInfo is signed 88 bool is0 = yes; 89 range(i, crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES) { 90 if (clientInfo[i]) { 91 is0 = no; 92 break; 93 } 94 } 95 96 if (is0) { 97 logN("Client id not checked"); 98 } 99 else { 100 // check client 101 // id key should already be known 102 u8 unsigned_message[crypto_sign_PUBLICKEYBYTES + sizeof(keys.remotePublicKey)] = init0Var; 103 unsigned long long unsigned_message_len; 104 105 if (crypto_sign_open(unsigned_message, &unsigned_message_len, clientInfo, sizeof(clientInfo), clientInfo + crypto_sign_BYTES) != 0) { 106 logE("Incorrect signature!"); 107 } 108 else { 109 logP("Correct client signature"); 110 } 111 } 112 113 memcpy(keys.remotePublicKey, clientInfo + crypto_sign_BYTES + crypto_sign_PUBLICKEYBYTES, sizeof(keys.remotePublicKey)); 114 115 logD("Remote public key"); 116 loghex(keys.remotePublicKey, sizeof(keys.remotePublicKey)); 117 put; 118 119 // send public key 120 u8 exchange[crypto_sign_PUBLICKEYBYTES + sizeof(keys.publicKey) + crypto_box_NONCEBYTES] = init0Var; 121 u8 signed_message[crypto_sign_BYTES + sizeof(exchange)] = init0Var; 122 unsigned long long signed_message_len = 0; 123 124 memcpy(exchange, identityKeys.publicKey, crypto_sign_PUBLICKEYBYTES); 125 memcpy(exchange + crypto_sign_PUBLICKEYBYTES, keys.publicKey, sizeof(keys.publicKey)); 126 memcpy(exchange + crypto_sign_PUBLICKEYBYTES + sizeof(keys.publicKey), sessionKeys.nonce, sizeof(sessionKeys.nonce)); 127 128 crypto_sign(signed_message, &signed_message_len, exchange, sizeof(exchange), identityKeys.secretKey); 129 130 if (!snd(signed_message, sizeof(signed_message))) continue; 131 132 // key exchange 133 if (not computeSharedKeys(SERVER_SESSION_KEYS)) { 134 logE("Invalid client key"); 135 exit(1); 136 } 137 138 // get encrypted message 139 int len; 140 // *nonce is incremented by after sending or receiving a message 141 // *nonce is allowed to wrap from the max value 142 u64 *nonce = (u64*)sessionKeys.nonce; 143 if (!rcv(&len, sizeof(len))) continue; 144 rcv(buf, len); 145 146 u8 decrypted[1000]; 147 logVarG(*nonce); 148 len = selDecrypt(decrypted, sizeof(decrypted), buf, len); 149 inc *nonce; 150 151 if (!len) { 152 logE("failed to decrypt"); 153 close(mysock); 154 continue; 155 } 156 157 decrypted[len] = 0; 158 159 logI("decrypted: %s", decrypted); 160 161 // send encrypted response 162 163 char *msg = "OK"; 164 165 logVarG(*nonce); 166 len = selEncrypt(buf, sizeof(buf), msg, strlen(msg)); 167 inc *nonce; 168 169 logVarG(len); 170 171 snd(&len, sizeof(len)); 172 snd(buf, len); 173 174 close(mysock); 175 } 176 } 177 } 178 // vim: set expandtab ts=2 sw=2: