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