implemented client-server connection, but found out RSA is broken

This commit is contained in:
2025-11-01 19:51:43 +05:00
parent 5cc1484e80
commit 8179609d47
21 changed files with 441 additions and 123 deletions

View File

@@ -1,10 +1,87 @@
#include "server.h"
#include "network/tcp-chat-protocol/v1.h"
void ClientConnection_close(ClientConnection* conn){
if(conn == NULL)
return;
socket_close(conn->system_socket.sock);
socket_close(conn->content_socket.sock);
socket_close(conn->sock.sock);
free(conn->session_key.data);
free(conn);
}
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
Socket sock_tcp, EndpointIPv4 client_end, u64 session_id)
{
Deferral(32);
ClientConnection* conn = (ClientConnection*)malloc(sizeof(ClientConnection));
memset(conn, 0, sizeof(*conn));
bool success = false;
Defer(
if(!success)
ClientConnection_close(conn);
);
conn->client_end = client_end;
conn->session_id = session_id;
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
Array(u8) enc_buf = Array_alloc_size(8*1024);
Defer(free(enc_buf.data));
Array(u8) dec_buf = Array_alloc_size(8*1024);
Defer(free(dec_buf.data));
u32 enc_size = 0, dec_size = 0;
// receive message encrypted by server public key
try(enc_size, u,
socket_recv(
sock_tcp,
Array_sliceBefore(enc_buf, server_credentials->rsa_pk.nlen),
SocketRecvFlag_WaitAll
)
);
// decrypt the message using server private key
RSADecryptor rsa_dec;
RSADecryptor_construct(&rsa_dec, &server_credentials->rsa_sk);
try(dec_size, u,
RSADecryptor_decrypt(
&rsa_dec,
Array_sliceBefore(enc_buf, enc_size)
)
);
// validate client handshake
if(dec_size != sizeof(ClientHandshake)){
Return RESULT_ERROR_FMT(
"decrypted message (size: %u) is not a ClientHandshake (size: %u)",
dec_size, (u32)sizeof(ClientHandshake)
);
}
ClientHandshake* client_handshake = dec_buf.data;
try_void(PacketHeader_validateMagic(&client_handshake->header));
if(client_handshake->header.type != PacketType_ClientHandshake){
Return RESULT_ERROR_FMT(
"received message of unexpected type: %u",
client_handshake->header.type
);
}
// use received session key
memcpy(conn->session_key.data, client_handshake->session_key, conn->session_key.size);
EncryptedSocketTCP_construct(&conn->sock, sock_tcp, conn->session_key);
// construct ServerHandshake in dec_buf
ServerHandshake_construct((ServerHandshake*)dec_buf.data, session_id);
// send ServerHandshake over encrypted TCP socket
try_void(
EncryptedSocketTCP_send(
&conn->sock,
Array_sliceBefore(dec_buf, sizeof(ServerHandshake)),
enc_buf
)
);
success = true;
Return RESULT_VALUE(p, conn);
}

View File

@@ -0,0 +1,26 @@
#include "server.h"
Result(ServerCredentials*) ServerCredentials_create(const str rsa_sk_base64, const str rsa_pk_base64){
Deferral(4);
ServerCredentials* cred = (ServerCredentials*)malloc(sizeof(ServerCredentials));
memset(cred, 0, sizeof(*cred));
bool success = false;
Defer(
if(!success)
ServerCredentials_free(cred);
);
try_void(RSA_parsePrivateKey_base64(rsa_sk_base64, &cred->rsa_sk));
try_void(RSA_parsePublicKey_base64(rsa_pk_base64, &cred->rsa_pk));
success = true;
Return RESULT_VALUE(p, cred);
}
void ServerCredentials_free(ServerCredentials* cred){
RSA_destroyPrivateKey(&cred->rsa_sk);
RSA_destroyPublicKey(&cred->rsa_pk);
free(cred);
}

View File

@@ -1,8 +1,9 @@
#include "server.h"
#include "db/idb.h"
#include <pthread.h>
static void* handle_connection(void* _args);
#include "tlibc/filesystem.h"
#include "db/idb.h"
#include "server.h"
#include "config.h"
#include "log.h"
typedef struct ConnectionHandlerArgs {
Socket accepted_socket;
@@ -10,22 +11,57 @@ typedef struct ConnectionHandlerArgs {
u64 session_id;
} ConnectionHandlerArgs;
Result(void) server_run(cstr server_endpoint_str){
static void* handle_connection(void* _args);
static Result(void) try_handle_connection(ConnectionHandlerArgs* args, cstr log_ctx);
static ServerCredentials* _server_credentials = NULL;
static Result(void) parseConfig(cstr config_path){
Deferral(8);
// open file
try(FILE* config_file, p, file_open(config_path, FO_ReadExisting));
// read whole file into Array(char)
try(i64 config_file_size, i, file_getSize(config_file));
Array(char) config_buf = Array_alloc(char, config_file_size);
Defer(free(config_buf.data));
try_void(file_readBytesArray(config_file, config_buf));
str config_str = Array_castTo_str(config_buf, false);
str sk_base64;
str pk_base64;
try_void(config_findValue(config_str, STR("rsa_private_key"), &sk_base64, true));
try_void(config_findValue(config_str, STR("rsa_public_key"), &pk_base64, true));
try(_server_credentials, p, ServerCredentials_create(sk_base64, pk_base64));
Return RESULT_VOID;
}
Result(void) server_run(cstr server_endpoint_cstr, cstr config_path){
Deferral(32);
cstr log_ctx = "Server/MainThread";
logInfo(log_ctx, "starting server");
logDebug(log_ctx, "parsing config");
try_void(parseConfig(config_path));
logDebug(log_ctx, "initializing main socket");
EndpointIPv4 server_end;
EndpointIPv4_parse(server_endpoint_str, &server_end);
//TODO: add log
EndpointIPv4_parse(server_endpoint_cstr, &server_end);
try(Socket main_socket, i, socket_open_TCP());
try_void(socket_bind(main_socket, server_end));
try_void(socket_listen(main_socket, 512));
logInfo(log_ctx, "server is listening at %s", server_endpoint_cstr);
u64 session_id = 1;
while(true){
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)malloc(sizeof(ConnectionHandlerArgs));
try(args->accepted_socket, i, socket_accept(main_socket, &args->client_end));
args->session_id = session_id++;
pthread_t conn_thread = {0};
//TODO: use async IO instead of threads to not waste system resources
// while waiting for incoming data in 100500 threads
try_stderrcode(pthread_create(&conn_thread, NULL, handle_connection, args));
}
@@ -33,13 +69,41 @@ Result(void) server_run(cstr server_endpoint_str){
}
static void* handle_connection(void* _args){
Deferral(64);
//ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)_args;
Defer(free(_args));
// TODO: receive handshake and session key
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)_args;
char log_ctx[64];
sprintf(log_ctx, "Session-" IFWIN("%llx", "%lx"), args->session_id);
//ClientConnection conn;
Result(void) r = try_handle_connection(args, log_ctx);
if(r.error){
str error_s = Error_toStr(r.error);
logError(log_ctx, "%s", error_s.data);
free(error_s.data);
}
Return NULL;
return NULL;
}
static Result(void) try_handle_connection(ConnectionHandlerArgs* args, cstr log_ctx){
Deferral(64);
Defer(free(args));
ClientConnection* conn = NULL;
Defer(ClientConnection_close(conn));
// establish encrypted connection
try(conn, p,
ClientConnection_accept(
_server_credentials,
args->accepted_socket,
args->client_end,
args->session_id
)
);
logDebug(log_ctx, "session accepted");
// handle requests
while(true){
sleepMsec(10);
}
Return RESULT_VOID;
}

View File

@@ -3,12 +3,33 @@
#include "cryptography/RSA.h"
#include "network/encrypted_sockets.h"
Result(void) server_run(cstr server_endpoint_str);
Result(void) server_run(cstr server_endpoint_cstr, cstr config_path);
typedef struct ServerCredentials {
br_rsa_private_key rsa_sk;
br_rsa_public_key rsa_pk;
} ServerCredentials;
Result(ServerCredentials*) ServerCredentials_create(const str rsa_sk_base64, const str rsa_pk_base64);
void ServerCredentials_free(ServerCredentials* cred);
typedef struct ServerMetadata {
str name;
str description;
} ServerMetadata;
typedef struct ClientConnection {
u64 session_id;
EndpointIPv4 client_end;
Array(u8) session_key;
EncryptedSocketTCP system_socket;
EncryptedSocketTCP content_socket;
EncryptedSocketTCP sock;
} ClientConnection;
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
Socket sock, EndpointIPv4 client_end, u64 session_id);
void ClientConnection_close(ClientConnection* conn);