refactored tlibc collections
This commit is contained in:
parent
7a3808ba59
commit
8bc98a321d
2
dependencies/tlibc
vendored
2
dependencies/tlibc
vendored
@ -1 +1 @@
|
||||
Subproject commit b557881168a15797bd3bd3d989cd7d48d3fb0804
|
||||
Subproject commit 82bd234d08e2556ae37fff8e414a72c5caaa355b
|
||||
@ -16,3 +16,5 @@
|
||||
#define CHANNEL_NAME_SIZE_MIN 1
|
||||
#define CHANNEL_NAME_SIZE_MAX 127
|
||||
#define CHANNEL_DESC_SIZE_MAX 1023
|
||||
#define MESSAGE_SIZE_MIN 1
|
||||
#define MESSAGE_SIZE_MAX 4000
|
||||
|
||||
@ -39,7 +39,7 @@ void ClientCLI_destroy(ClientCLI* self){
|
||||
Client_free(self->client);
|
||||
|
||||
idb_close(self->db);
|
||||
List_destroy(&self->servers.list);
|
||||
List_ServerInfo_destroy(&self->servers.list);
|
||||
HashMap_destroy(&self->servers.addr_id_map);
|
||||
}
|
||||
void ClientCLI_construct(ClientCLI* self){
|
||||
@ -51,7 +51,7 @@ Result(void) ClientCLI_run(ClientCLI* self) {
|
||||
|
||||
try_void(term_init());
|
||||
term_clear();
|
||||
printf(FMT_str"\n", greeting_art.size, greeting_art.data);
|
||||
printf(FMT_str"\n", greeting_art.len, greeting_art.data);
|
||||
|
||||
// create Client
|
||||
str username = str_null, password = str_null;
|
||||
@ -62,7 +62,7 @@ Result(void) ClientCLI_run(ClientCLI* self) {
|
||||
);
|
||||
Client_free(self->client);
|
||||
try(self->client, p, Client_create(username, password));
|
||||
memset(password.data, 0, password.size);
|
||||
memset(password.data, 0, password.len);
|
||||
|
||||
// init db
|
||||
try_void(ClientCLI_openUserDB(self));
|
||||
@ -77,14 +77,14 @@ Result(void) ClientCLI_run(ClientCLI* self) {
|
||||
|
||||
command_input = str_from_cstr(input_buf);
|
||||
str_trim(&command_input, true);
|
||||
if(command_input.size == 0)
|
||||
if(command_input.len == 0)
|
||||
continue;
|
||||
|
||||
ResultVar(void) com_result = ClientCLI_execCommand(self, command_input, &stop);
|
||||
if(com_result.error){
|
||||
Error_addCallPos(com_result.error, ErrorCallPos_here());
|
||||
str e_str = Error_toStr(com_result.error);
|
||||
printf("\n"FMT_str"\n", e_str.size, e_str.data);
|
||||
printf("\n"FMT_str"\n", e_str.len, e_str.data);
|
||||
str_free(e_str);
|
||||
Error_free(com_result.error);
|
||||
}
|
||||
@ -98,33 +98,33 @@ static Result(void) ClientCLI_askUserNameAndPassword(str* username_out, str* pas
|
||||
bool success = false;
|
||||
|
||||
// ask username
|
||||
Array(char) username_buf = Array_alloc_size(128);
|
||||
Defer(if(!success) Array_free(username_buf));
|
||||
Array(char) username_buf = Array_char_alloc(128);
|
||||
Defer(if(!success) Array_char_destroy(&username_buf));
|
||||
str username = str_null;
|
||||
while(true) {
|
||||
printf("username: ");
|
||||
try_void(term_readLine(username_buf.data, username_buf.size));
|
||||
try_void(term_readLine(username_buf.data, username_buf.len));
|
||||
username = str_from_cstr(username_buf.data);
|
||||
str_trim(&username, true);
|
||||
str name_error_str = validateUsername_str(username);
|
||||
if(name_error_str.data){
|
||||
printf("ERROR: "FMT_str"\n",
|
||||
name_error_str.size, name_error_str.data);
|
||||
name_error_str.len, name_error_str.data);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
// ask password
|
||||
Array(char) password_buf = Array_alloc_size(128);
|
||||
Defer(if(!success) Array_free(password_buf));
|
||||
Array(char) password_buf = Array_char_alloc(128);
|
||||
Defer(if(!success) Array_char_destroy(&password_buf));
|
||||
str password = str_null;
|
||||
while(true) {
|
||||
printf("password: ");
|
||||
// TODO: hide password
|
||||
try_void(term_readLineHidden(password_buf.data, password_buf.size));
|
||||
try_void(term_readLineHidden(password_buf.data, password_buf.len));
|
||||
password = str_from_cstr(password_buf.data);
|
||||
str_trim(&password, true);
|
||||
if(password.size < PASSWORD_SIZE_MIN || password.size > PASSWORD_SIZE_MAX){
|
||||
if(password.len < PASSWORD_SIZE_MIN || password.len > PASSWORD_SIZE_MAX){
|
||||
printf("ERROR: password length (in bytes) must be >= %i and <= %i\n",
|
||||
PASSWORD_SIZE_MIN, PASSWORD_SIZE_MAX);
|
||||
}
|
||||
@ -141,7 +141,7 @@ static Result(void) ClientCLI_execCommand(ClientCLI* self, str command, bool* st
|
||||
Deferral(64);
|
||||
|
||||
if(is_alias("q") || is_alias("quit") || is_alias("exit")){
|
||||
printf(FMT_str"\n", farewell_art.size, farewell_art.data);
|
||||
printf(FMT_str"\n", farewell_art.len, farewell_art.data);
|
||||
*stop = true;
|
||||
}
|
||||
else if(is_alias("clear")){
|
||||
@ -230,16 +230,16 @@ static Result(void) ClientCLI_selectServerFromCache(ClientCLI* self){
|
||||
idb_lockTable(self->servers.table);
|
||||
Defer(idb_unlockTable(self->servers.table));
|
||||
|
||||
u32 servers_count = List_len(self->servers.list, ServerInfo);
|
||||
u32 servers_count = self->servers.list.len;
|
||||
if(servers_count == 0){
|
||||
printf("No servers found in cache\n");
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
for(u32 id = 0; id < servers_count; id++){
|
||||
ServerInfo* row = &List_index(self->servers.list, ServerInfo, id);
|
||||
ServerInfo* server = self->servers.list.data + id;
|
||||
printf("[%02u] "FMT_str" "FMT_str"\n",
|
||||
id, row->address_len, row->address, row->name_len, row->name);
|
||||
id, server->address_len, server->address, server->name_len, server->name);
|
||||
}
|
||||
|
||||
char buf[32];
|
||||
@ -261,7 +261,7 @@ static Result(void) ClientCLI_selectServerFromCache(ClientCLI* self){
|
||||
}
|
||||
else break;
|
||||
}
|
||||
ServerInfo* server = &List_index(self->servers.list, ServerInfo, id);
|
||||
ServerInfo* server = self->servers.list.data + id;
|
||||
|
||||
printf("Connecting to '"FMT_str"'...\n", server->address_len, server->address);
|
||||
try_void(Client_connect(self->client, server->address, server->pk_base64));
|
||||
@ -273,9 +273,9 @@ static Result(void) ClientCLI_selectServerFromCache(ClientCLI* self){
|
||||
try_void(Client_getServerName(self->client, &name));
|
||||
if(!str_equals(name, str_construct(server->name, server->name_len, true))){
|
||||
server_info_changed = true;
|
||||
if(name.size > SERVER_NAME_SIZE_MAX)
|
||||
name.size = SERVER_NAME_SIZE_MAX;
|
||||
server->name_len = name.size;
|
||||
if(name.len > SERVER_NAME_SIZE_MAX)
|
||||
name.len = SERVER_NAME_SIZE_MAX;
|
||||
server->name_len = name.len;
|
||||
memcpy(server->name, name.data, server->name_len);
|
||||
}
|
||||
// update cached server description
|
||||
@ -283,9 +283,9 @@ static Result(void) ClientCLI_selectServerFromCache(ClientCLI* self){
|
||||
try_void(Client_getServerDescription(self->client, &desc));
|
||||
if(!str_equals(desc, str_construct(server->desc, server->desc_len, true))){
|
||||
server_info_changed = true;
|
||||
if(desc.size > SERVER_DESC_SIZE_MAX)
|
||||
desc.size = SERVER_DESC_SIZE_MAX;
|
||||
server->desc_len = desc.size;
|
||||
if(desc.len > SERVER_DESC_SIZE_MAX)
|
||||
desc.len = SERVER_DESC_SIZE_MAX;
|
||||
server->desc_len = desc.len;
|
||||
memcpy(server->desc, desc.data, server->desc_len);
|
||||
}
|
||||
if(server_info_changed){
|
||||
@ -335,7 +335,7 @@ static Result(void) ClientCLI_openUserDB(ClientCLI* self){
|
||||
|
||||
// load whole servers table to list
|
||||
try_void(
|
||||
idb_createListFromTable(self->servers.table, &self->servers.list, false)
|
||||
idb_createListFromTable(self->servers.table, (void*)&self->servers.list, false)
|
||||
);
|
||||
|
||||
// build address-id map
|
||||
@ -344,10 +344,12 @@ static Result(void) ClientCLI_openUserDB(ClientCLI* self){
|
||||
);
|
||||
HashMap_construct(&self->servers.addr_id_map, u64, NULL);
|
||||
for(u64 id = 0; id < servers_count; id++){
|
||||
ServerInfo* row = &List_index(self->servers.list, ServerInfo, id);
|
||||
str key = str_construct(row->address, row->address_len, true);
|
||||
ServerInfo* server = self->servers.list.data + id;
|
||||
str key = str_construct(server->address, server->address_len, true);
|
||||
if(!HashMap_tryPush(&self->servers.addr_id_map, key, &id)){
|
||||
Return RESULT_ERROR_FMT("duplicate server address '"FMT_str"'", key.size, key.data);
|
||||
Return RESULT_ERROR_FMT(
|
||||
"duplicate server address '"FMT_str"'",
|
||||
key.len, key.data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,24 +364,24 @@ static Result(ServerInfo*) ClientCLI_saveServerInfo(ClientCLI* self,
|
||||
ServerInfo server;
|
||||
memset(&server, 0, sizeof(ServerInfo));
|
||||
// address
|
||||
if(addr.size > HOSTADDR_SIZE_MAX)
|
||||
addr.size = HOSTADDR_SIZE_MAX;
|
||||
server.address_len = addr.size;
|
||||
if(addr.len > HOSTADDR_SIZE_MAX)
|
||||
addr.len = HOSTADDR_SIZE_MAX;
|
||||
server.address_len = addr.len;
|
||||
memcpy(server.address, addr.data, server.address_len);
|
||||
// public key
|
||||
if(pk_base64.size > PUBLIC_KEY_BASE64_SIZE_MAX)
|
||||
pk_base64.size = PUBLIC_KEY_BASE64_SIZE_MAX;
|
||||
server.pk_base64_len = pk_base64.size;
|
||||
if(pk_base64.len > PUBLIC_KEY_BASE64_SIZE_MAX)
|
||||
pk_base64.len = PUBLIC_KEY_BASE64_SIZE_MAX;
|
||||
server.pk_base64_len = pk_base64.len;
|
||||
memcpy(server.pk_base64, pk_base64.data, server.pk_base64_len);
|
||||
// name
|
||||
if(name.size > SERVER_NAME_SIZE_MAX)
|
||||
name.size = SERVER_NAME_SIZE_MAX;
|
||||
server.name_len = name.size;
|
||||
if(name.len > SERVER_NAME_SIZE_MAX)
|
||||
name.len = SERVER_NAME_SIZE_MAX;
|
||||
server.name_len = name.len;
|
||||
memcpy(server.name, name.data, server.name_len);
|
||||
// description
|
||||
if(desc.size > SERVER_DESC_SIZE_MAX)
|
||||
desc.size = SERVER_DESC_SIZE_MAX;
|
||||
server.desc_len = desc.size;
|
||||
if(desc.len > SERVER_DESC_SIZE_MAX)
|
||||
desc.len = SERVER_DESC_SIZE_MAX;
|
||||
server.desc_len = desc.len;
|
||||
memcpy(server.desc, desc.data, server.desc_len);
|
||||
|
||||
// Lock table until this function returns.
|
||||
@ -395,16 +397,16 @@ static Result(ServerInfo*) ClientCLI_saveServerInfo(ClientCLI* self,
|
||||
// update existing server
|
||||
u64 id = *id_ptr;
|
||||
try_void(idb_updateRow(self->servers.table, id, &server, false));
|
||||
try_assert(id < List_len(self->servers.list, ServerInfo));
|
||||
cached_row_ptr = &List_index(self->servers.list, ServerInfo, id);
|
||||
try_assert(id < self->servers.list.len);
|
||||
cached_row_ptr = self->servers.list.data + id;
|
||||
memcpy(cached_row_ptr, &server, sizeof(ServerInfo));
|
||||
}
|
||||
else {
|
||||
// push new server
|
||||
try(u64 id, u, idb_pushRow(self->servers.table, &server, false));
|
||||
try_assert(id == List_len(self->servers.list, ServerInfo));
|
||||
List_pushMany(&self->servers.list, ServerInfo, &server, 1);
|
||||
cached_row_ptr = &List_index(self->servers.list, ServerInfo, id);
|
||||
try_assert(id == self->servers.list.len);
|
||||
List_ServerInfo_pushMany(&self->servers.list, &server, 1);
|
||||
cached_row_ptr = self->servers.list.data + id;
|
||||
try_assert(HashMap_tryPush(&self->servers.addr_id_map, addr, &id));
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#include "db/idb.h"
|
||||
#include "db/tables.h"
|
||||
|
||||
List_declare(ServerInfo);
|
||||
|
||||
typedef struct ClientCLI {
|
||||
Client* client;
|
||||
IncrementalDB* db;
|
||||
|
||||
@ -8,13 +8,13 @@ Result(void) run_RandomBytes(u32 key_size) {
|
||||
printfe("generating random bytes...\n");
|
||||
br_hmac_drbg_context rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
rng_init_sha256_seedFromSystem(&rng.vtable);
|
||||
Array(u8) random_buf = Array_alloc_size(1024);
|
||||
u32 full_buffers_n = key_size / random_buf.size;
|
||||
u32 remaining_n = key_size % random_buf.size;
|
||||
Array(u8) random_buf = Array_u8_alloc(1024);
|
||||
u32 full_buffers_n = key_size / random_buf.len;
|
||||
u32 remaining_n = key_size % random_buf.len;
|
||||
while(full_buffers_n > 0){
|
||||
full_buffers_n--;
|
||||
br_hmac_drbg_generate(&rng, random_buf.data, random_buf.size);
|
||||
fwrite(random_buf.data, 1, random_buf.size, stdout);
|
||||
br_hmac_drbg_generate(&rng, random_buf.data, random_buf.len);
|
||||
fwrite(random_buf.data, 1, random_buf.len, stdout);
|
||||
}
|
||||
|
||||
br_hmac_drbg_generate(&rng, random_buf.data, remaining_n);
|
||||
@ -29,15 +29,15 @@ Result(void) run_RandomBytesBase64(u32 key_size) {
|
||||
printfe("generating random bytes...\n");
|
||||
br_hmac_drbg_context rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
rng_init_sha256_seedFromSystem(&rng.vtable);
|
||||
Array(u8) random_buf = Array_alloc_size(1024);
|
||||
Array(u8) base64_buf = Array_alloc_size(base64_encodedSize(random_buf.size));
|
||||
u32 full_buffers_n = key_size / random_buf.size;
|
||||
u32 remaining_n = key_size % random_buf.size;
|
||||
Array(u8) random_buf = Array_u8_alloc(1024);
|
||||
Array(char) base64_buf = Array_char_alloc(base64_encodedSize(random_buf.len));
|
||||
u32 full_buffers_n = key_size / random_buf.len;
|
||||
u32 remaining_n = key_size % random_buf.len;
|
||||
u32 enc_size = 0;
|
||||
while(full_buffers_n > 0){
|
||||
full_buffers_n--;
|
||||
br_hmac_drbg_generate(&rng, random_buf.data, random_buf.size);
|
||||
enc_size = base64_encode(random_buf.data, random_buf.size, base64_buf.data);
|
||||
br_hmac_drbg_generate(&rng, random_buf.data, random_buf.len);
|
||||
enc_size = base64_encode(random_buf.data, random_buf.len, base64_buf.data);
|
||||
fwrite(base64_buf.data, 1, enc_size, stdout);
|
||||
}
|
||||
|
||||
|
||||
@ -7,19 +7,19 @@ Result(void) run_RsaGenStdin(u32 key_size) {
|
||||
Deferral(4);
|
||||
|
||||
printfe("reading stdin...\n");
|
||||
Array(u8) input_buf = Array_alloc_size(64*1024);
|
||||
Defer(Array_free(input_buf));
|
||||
Array(u8) input_buf = Array_u8_alloc(64*1024);
|
||||
Defer(Array_u8_destroy(&input_buf));
|
||||
br_hmac_drbg_context rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
br_hmac_drbg_init(&rng, &br_sha256_vtable, NULL, 0);
|
||||
i64 read_n = 0;
|
||||
do {
|
||||
read_n = fread(input_buf.data, 1, input_buf.size, stdin);
|
||||
read_n = fread(input_buf.data, 1, input_buf.len, stdin);
|
||||
if(read_n < 0){
|
||||
Return RESULT_ERROR("ERROR: can't read stdin", false);
|
||||
}
|
||||
// put bytes to rng as seed
|
||||
br_hmac_drbg_update(&rng, input_buf.data, read_n);
|
||||
} while(read_n == input_buf.size);
|
||||
} while(read_n == input_buf.len);
|
||||
printfe("generating RSA key pair based on stdin...\n");
|
||||
br_rsa_private_key sk;
|
||||
br_rsa_public_key pk;
|
||||
|
||||
@ -29,10 +29,10 @@ Result(void) run_ServerMode(cstr config_path) {
|
||||
Defer(file_close(config_file));
|
||||
|
||||
// read whole file into str
|
||||
Array(u8) config_buf = Array_null;
|
||||
Array(u8) config_buf = Array_u8_construct(NULL, 0);
|
||||
try_void(file_readWhole(config_file, &config_buf));
|
||||
Defer(Array_free(config_buf));
|
||||
str config_str = Array_castTo_str(config_buf, false);
|
||||
Defer(Array_u8_destroy(&config_buf));
|
||||
str config_str = Array_u8_castTo_str(config_buf, false);
|
||||
|
||||
// init server
|
||||
try(Server* server, p, Server_create(config_str, NULL, log_func));
|
||||
@ -41,7 +41,7 @@ Result(void) run_ServerMode(cstr config_path) {
|
||||
// manually close file and free config_buf
|
||||
file_close(config_file);
|
||||
config_file = NULL;
|
||||
Array_free(config_buf);
|
||||
Array_u8_destroy(&config_buf);
|
||||
config_buf.data = NULL;
|
||||
|
||||
// start infinite loop on main thread
|
||||
|
||||
@ -6,8 +6,8 @@ void ServerConnection_close(ServerConnection* self){
|
||||
return;
|
||||
RSA_destroyPublicKey(&self->server_pk);
|
||||
EncryptedSocketTCP_destroy(&self->sock);
|
||||
Array_free(self->token);
|
||||
Array_free(self->session_key);
|
||||
Array_u8_destroy(&self->token);
|
||||
Array_u8_destroy(&self->session_key);
|
||||
str_free(self->server_name);
|
||||
str_free(self->server_description);
|
||||
free(self);
|
||||
@ -35,12 +35,12 @@ Result(ServerConnection*) ServerConnection_open(Client* client, cstr server_addr
|
||||
RSAEncryptor_construct(&conn->rsa_enc, &conn->server_pk);
|
||||
|
||||
// lvl 2 hash - is used for authentification
|
||||
conn->token = Array_alloc(u8, PASSWORD_HASH_SIZE);
|
||||
conn->token = Array_u8_alloc(PASSWORD_HASH_SIZE);
|
||||
// hash user_data_key with server_pk once
|
||||
Array(u8) server_pk_data = Array_construct_size(conn->server_pk.n,
|
||||
Array(u8) server_pk_data = Array_u8_construct(conn->server_pk.n,
|
||||
BR_RSA_KBUF_PUB_SIZE(conn->server_pk.nlen * 8));
|
||||
u8 server_pk_hash[PASSWORD_HASH_SIZE];
|
||||
Array(u8) server_pk_hash_array = Array_construct_size(server_pk_hash, PASSWORD_HASH_SIZE);
|
||||
Array(u8) server_pk_hash_array = Array_u8_construct(server_pk_hash, PASSWORD_HASH_SIZE);
|
||||
hash_password(conn->client->user_data_key, server_pk_data,
|
||||
server_pk_hash, 1);
|
||||
// hash user_data_key with server_pk_hash
|
||||
@ -48,10 +48,10 @@ Result(ServerConnection*) ServerConnection_open(Client* client, cstr server_addr
|
||||
conn->token.data, PASSWORD_HASH_LVL_ROUNDS);
|
||||
|
||||
// generate session random AES key
|
||||
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
|
||||
conn->session_key = Array_u8_alloc(AES_SESSION_KEY_SIZE);
|
||||
br_hmac_drbg_context key_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
rng_init_sha256_seedFromSystem(&key_rng.vtable);
|
||||
br_hmac_drbg_generate(&key_rng, conn->session_key.data, conn->session_key.size);
|
||||
br_hmac_drbg_generate(&key_rng, conn->session_key.data, conn->session_key.len);
|
||||
|
||||
// connect to server address
|
||||
try(Socket _s, i, socket_open_TCP());
|
||||
|
||||
@ -6,7 +6,7 @@ void Client_free(Client* self){
|
||||
return;
|
||||
|
||||
str_free(self->username);
|
||||
Array_free(self->user_data_key);
|
||||
Array_u8_destroy(&self->user_data_key);
|
||||
ServerConnection_close(self->conn);
|
||||
free(self);
|
||||
}
|
||||
@ -22,8 +22,8 @@ Result(Client*) Client_create(str username, str password){
|
||||
self->username = str_copy(username);
|
||||
|
||||
// lvl 1 hash - is used as AES key for user data
|
||||
self->user_data_key = Array_alloc(u8, PASSWORD_HASH_SIZE);
|
||||
hash_password(str_castTo_Array(password), str_castTo_Array(username),
|
||||
self->user_data_key = Array_u8_alloc(PASSWORD_HASH_SIZE);
|
||||
hash_password(str_castTo_Array_u8(password), str_castTo_Array_u8(username),
|
||||
self->user_data_key.data, PASSWORD_HASH_LVL_ROUNDS);
|
||||
|
||||
success = true;
|
||||
|
||||
@ -11,12 +11,12 @@ Result(void) recvStr(EncryptedSocketTCP* sock, u32 size, str* out_s){
|
||||
try_void(
|
||||
EncryptedSocketTCP_recv(
|
||||
sock,
|
||||
str_castTo_Array(s),
|
||||
str_castTo_Array_u8(s),
|
||||
SocketRecvFlag_WholeBuffer
|
||||
)
|
||||
);
|
||||
|
||||
s.data[s.size] = 0;
|
||||
s.data[s.len] = 0;
|
||||
*out_s = s;
|
||||
success = true;
|
||||
Return RESULT_VOID;
|
||||
@ -32,8 +32,8 @@ Result(void) recvErrorMessage(EncryptedSocketTCP* sock, PacketHeader* res_header
|
||||
try_void(EncryptedSocketTCP_recvStruct(sock, &res));
|
||||
// limit msg_size to fit in single EncryptedSocketTCP_recv call
|
||||
// TODO: receive ErrorMessage content in a loop
|
||||
if(res.msg_size > sock->recv_buf.size)
|
||||
res.msg_size = sock->recv_buf.size;
|
||||
if(res.msg_size > sock->recv_buf.len)
|
||||
res.msg_size = sock->recv_buf.len;
|
||||
|
||||
str err_msg;
|
||||
try_void(recvStr(sock, res.msg_size, &err_msg));
|
||||
|
||||
@ -15,7 +15,7 @@ Result(void) _recvResponse(EncryptedSocketTCP* sock,
|
||||
}
|
||||
|
||||
try_void(PacketHeader_validateType(res_header, res_type));
|
||||
try_void(PacketHeader_validateContentSize(res_header, res.size));
|
||||
try_void(PacketHeader_validateContentSize(res_header, res.len));
|
||||
|
||||
try_void(EncryptedSocketTCP_recv(sock, res, SocketRecvFlag_WholeBuffer));
|
||||
|
||||
|
||||
@ -11,10 +11,10 @@ Result(void) recvStr(EncryptedSocketTCP* sock, u32 size, str* out_s);
|
||||
Result(void) _recvResponse(EncryptedSocketTCP* sock,
|
||||
PacketHeader* res_header, Array(u8) res, PacketType res_type);
|
||||
#define recvResponse(sock, res_header_ptr, res_ptr, res_type) \
|
||||
_recvResponse(sock, res_header_ptr, struct_castTo_Array(res_ptr), res_type)
|
||||
_recvResponse(sock, res_header_ptr, struct_castTo_Array_u8(res_ptr), res_type)
|
||||
|
||||
|
||||
Result(void) _sendRequest(EncryptedSocketTCP* sock,
|
||||
PacketHeader* req_header, Array(u8) req);
|
||||
#define sendRequest(sock, req_header_ptr, req_ptr) \
|
||||
_sendRequest(sock, req_header_ptr, struct_castTo_Array(req_ptr))
|
||||
_sendRequest(sock, req_header_ptr, struct_castTo_Array_u8(req_ptr))
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
|
||||
Result(void) config_findValue(str config_str, str key, str* value, bool throwNotFoundError){
|
||||
u32 line_n = 0;
|
||||
while(config_str.size > 0){
|
||||
while(config_str.len > 0){
|
||||
line_n++;
|
||||
i32 line_end = str_seekChar(config_str, '\n', 0);
|
||||
if(line_end < 0)
|
||||
line_end = config_str.size - 1;
|
||||
line_end = config_str.len - 1;
|
||||
str line = str_sliceBefore(config_str, line_end);
|
||||
config_str = str_sliceAfter(config_str, line_end + 1);
|
||||
|
||||
@ -27,7 +27,7 @@ Result(void) config_findValue(str config_str, str key, str* value, bool throwNot
|
||||
}
|
||||
|
||||
if(throwNotFoundError){
|
||||
char* err_msg = sprintf_malloc("can't find key '"FMT_str"'", key.size, key.data);
|
||||
char* err_msg = sprintf_malloc("can't find key '"FMT_str"'", key.len, key.data);
|
||||
return RESULT_ERROR(err_msg, true);
|
||||
}
|
||||
return RESULT_VOID;
|
||||
|
||||
@ -4,19 +4,19 @@
|
||||
// write data from src to array and increment array data pointer
|
||||
static inline void __Array_writeNext(Array(u8)* dst, u8* src, size_t size){
|
||||
memcpy(dst->data, src, size);
|
||||
*dst = Array_sliceFrom(*dst, size);
|
||||
*dst = Array_u8_sliceFrom(*dst, size);
|
||||
}
|
||||
|
||||
// read data from array to dst and increment array data pointer
|
||||
static inline void __Array_readNext(u8* dst, Array(u8)* src, size_t size){
|
||||
memcpy(dst, src->data, size);
|
||||
*src = Array_sliceFrom(*src, size);
|
||||
*src = Array_u8_sliceFrom(*src, size);
|
||||
}
|
||||
|
||||
static void __calcKeyCheckSum(Array(u8) key, void* dst){
|
||||
br_sha256_context sha_ctx;
|
||||
br_sha256_init(&sha_ctx);
|
||||
br_sha256_update(&sha_ctx, key.data, key.size);
|
||||
br_sha256_update(&sha_ctx, key.data, key.len);
|
||||
br_sha256_out(&sha_ctx, dst);
|
||||
}
|
||||
|
||||
@ -37,8 +37,8 @@ void AESBlockEncryptor_construct(AESBlockEncryptor* ptr,
|
||||
|
||||
void AESBlockEncryptor_changeKey(AESBlockEncryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->enc_class->init((void*)ptr->enc_keys, key.data, key.size);
|
||||
assert(key.len == 16 || key.len == 24 || key.len == 32);
|
||||
ptr->enc_class->init((void*)ptr->enc_keys, key.data, key.len);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
@ -46,8 +46,8 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
Array(u8) src, Array(u8) dst)
|
||||
{
|
||||
Deferral(4);
|
||||
u32 encrypted_size = AESBlockEncryptor_calcDstSize(src.size);
|
||||
try_assert(dst.size >= encrypted_size);
|
||||
u32 encrypted_size = AESBlockEncryptor_calcDstSize(src.len);
|
||||
try_assert(dst.len >= encrypted_size);
|
||||
|
||||
// generate random initial vector
|
||||
br_hmac_drbg_generate(&ptr->rng_ctx, ptr->iv, __AES_BLOCK_IV_SIZE);
|
||||
@ -57,7 +57,7 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
EncryptedBlockHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
memcpy(header.key_checksum, ptr->key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
header.padding_size = (16 - src.size % 16) % 16;
|
||||
header.padding_size = (16 - src.len % 16) % 16;
|
||||
// write header to buffer
|
||||
memcpy(ptr->buf, &header, sizeof(header));
|
||||
// encrypt header
|
||||
@ -66,7 +66,7 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
__Array_writeNext(&dst, ptr->buf, sizeof(header));
|
||||
|
||||
// encrypt full AESBlockEncryptor buffers
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
while(src.len > __AES_BUFFER_SIZE){
|
||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
||||
ptr->enc_class->run((void*)ptr->enc_keys,
|
||||
ptr->iv,
|
||||
@ -75,10 +75,10 @@ Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr,
|
||||
}
|
||||
|
||||
// encrypt buffer with remaining data
|
||||
if(src.size > 0){
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
memset(ptr->buf + src.size, 0, header.padding_size);
|
||||
u32 src_size_padded = src.size + header.padding_size;
|
||||
if(src.len > 0){
|
||||
memcpy(ptr->buf, src.data, src.len);
|
||||
memset(ptr->buf + src.len, 0, header.padding_size);
|
||||
u32 src_size_padded = src.len + header.padding_size;
|
||||
ptr->enc_class->run((void*)ptr->enc_keys,
|
||||
ptr->iv,
|
||||
ptr->buf, src_size_padded);
|
||||
@ -102,8 +102,8 @@ void AESBlockDecryptor_construct(AESBlockDecryptor* ptr,
|
||||
|
||||
void AESBlockDecryptor_changeKey(AESBlockDecryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->dec_class->init((void*)ptr->dec_keys, key.data, key.size);
|
||||
assert(key.len == 16 || key.len == 24 || key.len == 32);
|
||||
ptr->dec_class->init((void*)ptr->dec_keys, key.data, key.len);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
@ -112,9 +112,9 @@ Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
|
||||
{
|
||||
Deferral(4);
|
||||
u32 overhead_size = AESBlockEncryptor_calcDstSize(0);
|
||||
try_assert(src.size >= overhead_size);
|
||||
try_assert(src.size % 16 == 0 && "src must be array of 16-byte blocks");
|
||||
try_assert(dst.size >= src.size - overhead_size);
|
||||
try_assert(src.len >= overhead_size);
|
||||
try_assert(src.len % 16 == 0 && "src must be array of 16-byte blocks");
|
||||
try_assert(dst.len >= src.len - overhead_size);
|
||||
|
||||
// read IV from the beginning of src
|
||||
__Array_readNext(ptr->iv, &src, __AES_BLOCK_IV_SIZE);
|
||||
@ -131,12 +131,12 @@ Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
|
||||
}
|
||||
|
||||
// size of decrypted data without padding
|
||||
try_assert(src.size >= header.padding_size && "invalid padding size");
|
||||
u32 decrypted_size = src.size - header.padding_size;
|
||||
src.size = decrypted_size;
|
||||
try_assert(src.len >= header.padding_size && "invalid padding size");
|
||||
u32 decrypted_size = src.len - header.padding_size;
|
||||
src.len = decrypted_size;
|
||||
|
||||
// decrypt full buffers
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
while(src.len > __AES_BUFFER_SIZE){
|
||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
||||
ptr->dec_class->run((void*)ptr->dec_keys,
|
||||
ptr->iv,
|
||||
@ -145,14 +145,14 @@ Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr,
|
||||
}
|
||||
|
||||
// decrypt buffer with remaining data
|
||||
if(src.size > 0){
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
memset(ptr->buf + src.size, 0, header.padding_size);
|
||||
u32 src_size_padded = src.size + header.padding_size;
|
||||
if(src.len > 0){
|
||||
memcpy(ptr->buf, src.data, src.len);
|
||||
memset(ptr->buf + src.len, 0, header.padding_size);
|
||||
u32 src_size_padded = src.len + header.padding_size;
|
||||
ptr->dec_class->run((void*)ptr->dec_keys,
|
||||
ptr->iv,
|
||||
ptr->buf, src_size_padded);
|
||||
memcpy(dst.data, ptr->buf, src.size);
|
||||
memcpy(dst.data, ptr->buf, src.len);
|
||||
}
|
||||
|
||||
Return RESULT_VALUE(u, decrypted_size);
|
||||
@ -178,8 +178,8 @@ void AESStreamEncryptor_construct(AESStreamEncryptor* ptr,
|
||||
|
||||
void AESStreamEncryptor_changeKey(AESStreamEncryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
|
||||
assert(key.len == 16 || key.len == 24 || key.len == 32);
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.len);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
{
|
||||
Deferral(4);
|
||||
|
||||
u32 encrypted_size = src.size;
|
||||
u32 encrypted_size = src.len;
|
||||
// if it is the beginning of the stream,
|
||||
if(ptr->block_counter == 0){
|
||||
// write IV generated during initialization
|
||||
@ -204,10 +204,10 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
// write checksum to dst
|
||||
__Array_writeNext(&dst, key_checksum, __AES_BLOCK_KEY_CHECKSUM_SIZE);
|
||||
}
|
||||
try_assert(dst.size >= encrypted_size);
|
||||
try_assert(dst.len >= encrypted_size);
|
||||
|
||||
// encrypt full buffers
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
while(src.len > __AES_BUFFER_SIZE){
|
||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
@ -216,12 +216,12 @@ Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr,
|
||||
}
|
||||
|
||||
// encrypt remaining data
|
||||
if(src.size > 0){
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
if(src.len > 0){
|
||||
memcpy(ptr->buf, src.data, src.len);
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
ptr->buf, src.size);
|
||||
memcpy(dst.data, ptr->buf, src.size);
|
||||
ptr->buf, src.len);
|
||||
memcpy(dst.data, ptr->buf, src.len);
|
||||
}
|
||||
|
||||
Return RESULT_VALUE(u, encrypted_size);
|
||||
@ -242,8 +242,8 @@ void AESStreamDecryptor_construct(AESStreamDecryptor* ptr,
|
||||
|
||||
void AESStreamDecryptor_changeKey(AESStreamDecryptor* ptr, Array(u8) key)
|
||||
{
|
||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.size);
|
||||
assert(key.len == 16 || key.len == 24 || key.len == 32);
|
||||
ptr->ctr_class->init((void*)ptr->ctr_keys, key.data, key.len);
|
||||
__calcKeyCheckSum(key, ptr->key_checksum);
|
||||
}
|
||||
|
||||
@ -270,11 +270,11 @@ Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
|
||||
}
|
||||
}
|
||||
// size without IV
|
||||
u32 decrypted_size = src.size;
|
||||
try_assert(dst.size >= decrypted_size);
|
||||
u32 decrypted_size = src.len;
|
||||
try_assert(dst.len >= decrypted_size);
|
||||
|
||||
// decrypt full buffers
|
||||
while(src.size > __AES_BUFFER_SIZE){
|
||||
while(src.len > __AES_BUFFER_SIZE){
|
||||
__Array_readNext(ptr->buf, &src, __AES_BUFFER_SIZE);
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
@ -283,12 +283,12 @@ Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr,
|
||||
}
|
||||
|
||||
// decrypt remaining data
|
||||
if(src.size > 0){
|
||||
memcpy(ptr->buf, src.data, src.size);
|
||||
if(src.len > 0){
|
||||
memcpy(ptr->buf, src.data, src.len);
|
||||
ptr->block_counter = ptr->ctr_class->run((void*)ptr->ctr_keys,
|
||||
ptr->iv, ptr->block_counter,
|
||||
ptr->buf, src.size);
|
||||
memcpy(dst.data, ptr->buf, src.size);
|
||||
ptr->buf, src.len);
|
||||
memcpy(dst.data, ptr->buf, src.len);
|
||||
}
|
||||
|
||||
Return RESULT_VALUE(u, decrypted_size);
|
||||
|
||||
@ -48,7 +48,7 @@ void AESBlockEncryptor_changeKey(AESBlockEncryptor* ptr, Array(u8) key);
|
||||
|
||||
/// @brief Encrypts a complete message. For part-by-part encryption use AESStreamEncryptor.
|
||||
/// @param src array of any size
|
||||
/// @param dst array of size >= AESBlockEncryptor_calcDstSize(src.size)
|
||||
/// @param dst array of size >= AESBlockEncryptor_calcDstSize(src.len)
|
||||
/// @return size of encrypted data
|
||||
Result(u32) AESBlockEncryptor_encrypt(AESBlockEncryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
@ -75,7 +75,7 @@ void AESBlockDecryptor_changeKey(AESBlockDecryptor* ptr, Array(u8) key);
|
||||
|
||||
/// @brief Decrypts a complete message. For part-by-part decryption use AESStreamEncryptor.
|
||||
/// @param src array of size at least AESBlockEncryptor_calcDstSize(0). Size must be multiple of 16.
|
||||
/// @param dst array of size >= src.size
|
||||
/// @param dst array of size >= src.len
|
||||
/// @return size of decrypted data
|
||||
Result(u32) AESBlockDecryptor_decrypt(AESBlockDecryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
@ -107,7 +107,7 @@ void AESStreamEncryptor_changeKey(AESStreamEncryptor* ptr, Array(u8) key);
|
||||
|
||||
/// @brief If ptr->block_counter == 0, writes random IV to `dst`. After that writes encrypted data to dst.
|
||||
/// @param src array of any size
|
||||
/// @param dst array of size >= `AESStreamEncryptor_calcDstSize(src.size)` for first block and `src.size `for other blocks
|
||||
/// @param dst array of size >= `AESStreamEncryptor_calcDstSize(src.len)` for first block and `src.len `for other blocks
|
||||
/// @return size of encrypted data
|
||||
Result(u32) AESStreamEncryptor_encrypt(AESStreamEncryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
@ -134,6 +134,6 @@ void AESStreamDecryptor_changeKey(AESStreamDecryptor* ptr, Array(u8) key);
|
||||
|
||||
/// @brief Reads IV from `src`, then decrypts data and writes it to dst
|
||||
/// @param src array of any size
|
||||
/// @param dst array of size >= src.size
|
||||
/// @param dst array of size >= src.len
|
||||
/// @return size of decrypted data
|
||||
Result(u32) AESStreamDecryptor_decrypt(AESStreamDecryptor* ptr, Array(u8) src, Array(u8) dst);
|
||||
|
||||
@ -46,7 +46,7 @@ Result(void) RSA_generateKeyPairFromPassword(u32 key_size,
|
||||
{
|
||||
Deferral(4);
|
||||
br_hmac_drbg_context password_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
br_hmac_drbg_init(&password_based_rng, &br_sha256_vtable, password.data, password.size);
|
||||
br_hmac_drbg_init(&password_based_rng, &br_sha256_vtable, password.data, password.len);
|
||||
try_void(RSA_generateKeyPair(key_size, sk, pk, &password_based_rng.vtable));
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
@ -129,12 +129,12 @@ Result(void) RSA_parsePublicKey_base64(cstr src, br_rsa_public_key* pk){
|
||||
}
|
||||
str key_base64_str = src_str;
|
||||
key_base64_str.data += offset;
|
||||
key_base64_str.size -= offset;
|
||||
u32 decoded_size = base64_decodedSize(key_base64_str.data, key_base64_str.size);
|
||||
key_base64_str.len -= offset;
|
||||
u32 decoded_size = base64_decodedSize(key_base64_str.data, key_base64_str.len);
|
||||
if(decoded_size != key_buffer_size){
|
||||
Return RESULT_ERROR_FMT("decoded key size is %u, must be %u", decoded_size, key_buffer_size);
|
||||
}
|
||||
decoded_size = base64_decode(key_base64_str.data, key_base64_str.size, pk->n);
|
||||
decoded_size = base64_decode(key_base64_str.data, key_base64_str.len, pk->n);
|
||||
if(decoded_size != key_buffer_size){
|
||||
Return RESULT_ERROR("key decoding failed", false);
|
||||
}
|
||||
@ -163,12 +163,12 @@ Result(void) RSA_parsePrivateKey_base64(cstr src, br_rsa_private_key* sk){
|
||||
}
|
||||
str key_base64_str = src_str;
|
||||
key_base64_str.data += offset;
|
||||
key_base64_str.size -= offset;
|
||||
u32 decoded_size = base64_decodedSize(key_base64_str.data, key_base64_str.size);
|
||||
key_base64_str.len -= offset;
|
||||
u32 decoded_size = base64_decodedSize(key_base64_str.data, key_base64_str.len);
|
||||
if(decoded_size != key_buffer_size){
|
||||
Return RESULT_ERROR_FMT("decoded key size is %u, must be %u", decoded_size, key_buffer_size);
|
||||
}
|
||||
decoded_size = base64_decode(key_base64_str.data, key_base64_str.size, sk->p);
|
||||
decoded_size = base64_decode(key_base64_str.data, key_base64_str.len, sk->p);
|
||||
if(decoded_size != key_buffer_size){
|
||||
Return RESULT_ERROR("key decoding failed", false);
|
||||
}
|
||||
@ -189,20 +189,20 @@ void RSAEncryptor_construct(RSAEncryptor* ptr, const br_rsa_public_key* pk){
|
||||
Result(u32) RSAEncryptor_encrypt(RSAEncryptor* ptr, Array(u8) src, Array(u8) dst){
|
||||
u32 key_size_bytes = ptr->pk->nlen;
|
||||
const u32 max_src_size = RSAEncryptor_calcMaxSrcSize(key_size_bytes * 8, 256);
|
||||
if(src.size > max_src_size){
|
||||
return RESULT_ERROR_FMT("src.size (%u) must be <= RSAEncryptor_calcMaxSrcSize() (%u)",
|
||||
src.size, max_src_size);
|
||||
if(src.len > max_src_size){
|
||||
return RESULT_ERROR_FMT("src.len (%u) must be <= RSAEncryptor_calcMaxSrcSize() (%u)",
|
||||
src.len, max_src_size);
|
||||
}
|
||||
if(dst.size < key_size_bytes){
|
||||
return RESULT_ERROR_FMT("dst.size (%u) must be >= key length in bytes (%u)",
|
||||
dst.size, key_size_bytes);
|
||||
if(dst.len < key_size_bytes){
|
||||
return RESULT_ERROR_FMT("dst.len (%u) must be >= key length in bytes (%u)",
|
||||
dst.len, key_size_bytes);
|
||||
}
|
||||
size_t sz = br_rsa_i31_oaep_encrypt(
|
||||
&ptr->rng.vtable, &br_sha256_vtable,
|
||||
NULL, 0,
|
||||
ptr->pk,
|
||||
dst.data, dst.size,
|
||||
src.data, src.size);
|
||||
dst.data, dst.len,
|
||||
src.data, src.len);
|
||||
|
||||
if(sz == 0){
|
||||
return RESULT_ERROR("RSA encryption failed", false);
|
||||
@ -221,12 +221,12 @@ void RSADecryptor_construct(RSADecryptor* ptr, const br_rsa_private_key* sk){
|
||||
|
||||
Result(u32) RSADecryptor_decrypt(RSADecryptor* ptr, Array(u8) buffer){
|
||||
u32 key_size_bits = ptr->sk->n_bitlen;
|
||||
if(buffer.size != key_size_bits/8){
|
||||
return RESULT_ERROR_FMT("buffer.size (%u) must be == key length in bytes (%u)",
|
||||
buffer.size, key_size_bits/8);
|
||||
if(buffer.len != key_size_bits/8){
|
||||
return RESULT_ERROR_FMT("buffer.len (%u) must be == key length in bytes (%u)",
|
||||
buffer.len, key_size_bits/8);
|
||||
}
|
||||
|
||||
size_t sz = buffer.size;
|
||||
size_t sz = buffer.len;
|
||||
size_t r = br_rsa_i31_oaep_decrypt(
|
||||
&br_sha256_vtable,
|
||||
NULL, 0,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "tlibc/collections/Array.h"
|
||||
#include "tlibc/errors.h"
|
||||
#include "tlibc/collections/Array.h"
|
||||
#include "tlibc/collections/Array_impl/Array_u8.h"
|
||||
#include "bearssl_rand.h"
|
||||
#include "bearssl_hash.h"
|
||||
#include "tcp-chat/common_constants.h"
|
||||
|
||||
@ -8,8 +8,8 @@ void hash_password(Array(u8) password, Array(u8) salt, u8* out_buffer, i32 itera
|
||||
br_sha256_init(&sha256_ctx);
|
||||
|
||||
for(i32 i = 0; i < iterations; i++){
|
||||
br_sha256_update(&sha256_ctx, password.data, password.size);
|
||||
br_sha256_update(&sha256_ctx, salt.data, salt.size);
|
||||
br_sha256_update(&sha256_ctx, password.data, password.len);
|
||||
br_sha256_update(&sha256_ctx, salt.data, salt.len);
|
||||
br_sha256_out(&sha256_ctx, out_buffer);
|
||||
br_sha256_update(&sha256_ctx, out_buffer, PASSWORD_HASH_SIZE);
|
||||
}
|
||||
|
||||
49
src/db/idb.c
49
src/db/idb.c
@ -53,7 +53,7 @@ static void Table_close(Table* t){
|
||||
str_free(t->table_file_path);
|
||||
str_free(t->changes_file_path);
|
||||
pthread_mutex_destroy(&t->mutex);
|
||||
Array_free(t->enc_buf);
|
||||
Array_u8_destroy(&t->enc_buf);
|
||||
free(t);
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ static Result(void) Table_validateHeader(Table* t){
|
||||
static Result(void) Table_validateEncryption(Table* t){
|
||||
Deferral(1);
|
||||
|
||||
bool db_encrypted = t->db->aes_key.size != 0;
|
||||
bool db_encrypted = t->db->aes_key.len != 0;
|
||||
if(t->header.encrypted && !db_encrypted){
|
||||
Return RESULT_ERROR_FMT(
|
||||
"Table '%s' is encrypted, but encryption key is not set."
|
||||
@ -179,7 +179,7 @@ static Result(void) Table_validateEncryption(Table* t){
|
||||
try_void(
|
||||
AESBlockDecryptor_decrypt(
|
||||
&t->dec,
|
||||
Array_construct_size(t->header.key_challenge, KEY_CHALLENGE_CIPHER_SIZE),
|
||||
Array_u8_construct(t->header.key_challenge, KEY_CHALLENGE_CIPHER_SIZE),
|
||||
t->enc_buf
|
||||
)
|
||||
);
|
||||
@ -208,7 +208,7 @@ void idb_close(IncrementalDB* db){
|
||||
if(db == NULL)
|
||||
return;
|
||||
str_free(db->db_dir);
|
||||
Array_free(db->aes_key);
|
||||
Array_u8_destroy(&db->aes_key);
|
||||
HashMap_destroy(&db->tables_map);
|
||||
pthread_mutex_destroy(&db->mutex);
|
||||
free(db);
|
||||
@ -216,7 +216,7 @@ void idb_close(IncrementalDB* db){
|
||||
|
||||
Result(IncrementalDB*) idb_open(str db_dir, NULLABLE(Array(u8) aes_key)){
|
||||
Deferral(16);
|
||||
try_assert(aes_key.size == 0 || aes_key.size == 16 || aes_key.size == 24 || aes_key.size == 32);
|
||||
try_assert(aes_key.len == 0 || aes_key.len == 16 || aes_key.len == 24 || aes_key.len == 32);
|
||||
|
||||
IncrementalDB* db = (IncrementalDB*)malloc(sizeof(IncrementalDB));
|
||||
// value of *db must be set to zero or behavior of idb_close will be undefined
|
||||
@ -225,8 +225,8 @@ Result(IncrementalDB*) idb_open(str db_dir, NULLABLE(Array(u8) aes_key)){
|
||||
bool success = false;
|
||||
Defer(if(!success) idb_close(db));
|
||||
|
||||
if(aes_key.size != 0){
|
||||
db->aes_key = Array_copy(aes_key);
|
||||
if(aes_key.len != 0){
|
||||
db->aes_key = Array_u8_copy(aes_key);
|
||||
}
|
||||
|
||||
db->db_dir = str_copy(db_dir);
|
||||
@ -295,11 +295,11 @@ Result(Table*) idb_getOrCreateTable(IncrementalDB* db, str table_name, u32 row_s
|
||||
try(t->changes_file, p, file_openOrCreateReadWrite(t->changes_file_path.data));
|
||||
|
||||
// init encryptor and decryptor now to use them in table header validation/creation
|
||||
if(db->aes_key.size != 0) {
|
||||
if(db->aes_key.len != 0) {
|
||||
AESBlockEncryptor_construct(&t->enc, db->aes_key, AESBlockEncryptor_DEFAULT_CLASS);
|
||||
AESBlockDecryptor_construct(&t->dec, db->aes_key, AESBlockDecryptor_DEFAULT_CLASS);
|
||||
u32 row_size_in_file = AESBlockEncryptor_calcDstSize(row_size);
|
||||
t->enc_buf = Array_alloc_size(row_size_in_file);
|
||||
t->enc_buf = Array_u8_alloc(row_size_in_file);
|
||||
}
|
||||
|
||||
// init header
|
||||
@ -315,15 +315,15 @@ Result(Table*) idb_getOrCreateTable(IncrementalDB* db, str table_name, u32 row_s
|
||||
// create table file
|
||||
t->header.magic.n = TABLE_FILE_MAGIC.n;
|
||||
t->header.version = IDB_VERSION;
|
||||
t->header.encrypted = db->aes_key.size != 0;
|
||||
t->header.encrypted = db->aes_key.len != 0;
|
||||
t->header._dirty_bit = false;
|
||||
t->header.row_size = row_size;
|
||||
memset(t->header.key_challenge, 0, KEY_CHALLENGE_CIPHER_SIZE);
|
||||
try_void(
|
||||
AESBlockEncryptor_encrypt(
|
||||
&t->enc,
|
||||
Array_construct_size((void*)KEY_CHALLENGE_PLAIN, KEY_CHALLENGE_PLAIN_SIZE),
|
||||
Array_construct_size(t->header.key_challenge, KEY_CHALLENGE_CIPHER_SIZE)
|
||||
Array_u8_construct((void*)KEY_CHALLENGE_PLAIN, KEY_CHALLENGE_PLAIN_SIZE),
|
||||
Array_u8_construct(t->header.key_challenge, KEY_CHALLENGE_CIPHER_SIZE)
|
||||
)
|
||||
);
|
||||
try_void(Table_writeHeader(t));
|
||||
@ -355,7 +355,7 @@ Result(void) idb_getRows(Table* t, u64 id, void* dst, u64 count, bool lock_table
|
||||
}
|
||||
|
||||
u32 row_size = t->header.row_size;
|
||||
u32 row_size_in_file = t->header.encrypted ? t->enc_buf.size : row_size;
|
||||
u32 row_size_in_file = t->header.encrypted ? t->enc_buf.len : row_size;
|
||||
i64 file_pos = sizeof(t->header) + id * row_size_in_file;
|
||||
|
||||
// seek for the row position in file
|
||||
@ -373,7 +373,7 @@ Result(void) idb_getRows(Table* t, u64 id, void* dst, u64 count, bool lock_table
|
||||
AESBlockDecryptor_decrypt(
|
||||
&t->dec,
|
||||
t->enc_buf,
|
||||
Array_construct_size(row_ptr, row_size)
|
||||
Array_u8_construct(row_ptr, row_size)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -401,7 +401,7 @@ Result(void) idb_updateRows(Table* t, u64 id, const void* src, u64 count, bool l
|
||||
Defer(IGNORE_RESULT Table_setDirtyBit(t, false));
|
||||
|
||||
u32 row_size = t->header.row_size;
|
||||
u32 row_size_in_file = t->header.encrypted ? t->enc_buf.size : row_size;
|
||||
u32 row_size_in_file = t->header.encrypted ? t->enc_buf.len : row_size;
|
||||
i64 file_pos = sizeof(t->header) + id * row_size_in_file;
|
||||
|
||||
// TODO: set dirty bit in backup file too
|
||||
@ -417,7 +417,7 @@ Result(void) idb_updateRows(Table* t, u64 id, const void* src, u64 count, bool l
|
||||
try_void(
|
||||
AESBlockEncryptor_encrypt(
|
||||
&t->enc,
|
||||
Array_construct_size(row_ptr, row_size),
|
||||
Array_u8_construct(row_ptr, row_size),
|
||||
t->enc_buf
|
||||
)
|
||||
);
|
||||
@ -441,7 +441,7 @@ Result(u64) idb_pushRows(Table* t, const void* src, u64 count, bool lock_table){
|
||||
Defer(IGNORE_RESULT Table_setDirtyBit(t, false));
|
||||
|
||||
u32 row_size = t->header.row_size;
|
||||
u32 row_size_in_file = t->header.encrypted ? t->enc_buf.size : row_size;
|
||||
u32 row_size_in_file = t->header.encrypted ? t->enc_buf.len : row_size;
|
||||
const u64 new_row_index = t->row_count;
|
||||
|
||||
// seek for end of the file
|
||||
@ -454,7 +454,7 @@ Result(u64) idb_pushRows(Table* t, const void* src, u64 count, bool lock_table){
|
||||
try_void(
|
||||
AESBlockEncryptor_encrypt(
|
||||
&t->enc,
|
||||
Array_construct_size(row_ptr, row_size),
|
||||
Array_u8_construct(row_ptr, row_size),
|
||||
t->enc_buf
|
||||
)
|
||||
);
|
||||
@ -487,14 +487,15 @@ Result(void) idb_createListFromTable(Table* t, List_* l, bool lock_table){
|
||||
Defer(idb_unlockTable(t));
|
||||
}
|
||||
|
||||
u64 rows_count = t->row_count;
|
||||
u64 total_size = rows_count * t->header.row_size;
|
||||
*l = List_alloc_size(total_size);
|
||||
l->size = total_size;
|
||||
u64 row_count = t->row_count;
|
||||
u64 row_size = t->header.row_size;
|
||||
u64 total_size = row_count * row_size;
|
||||
*l = _List_alloc(total_size, row_size);
|
||||
l->len = row_count;
|
||||
bool success = false;
|
||||
Defer(if(!success) List_destroy(l));
|
||||
Defer(if(!success) _List_destroy(l));
|
||||
|
||||
try_void(idb_getRows(t, 0, l->data, rows_count, false));
|
||||
try_void(idb_getRows(t, 0, l->data, row_count, false));
|
||||
|
||||
success = true;
|
||||
Return RESULT_VOID;
|
||||
|
||||
@ -10,16 +10,16 @@ void EncryptedSocketTCP_construct(EncryptedSocketTCP* ptr,
|
||||
ptr->sock = sock;
|
||||
AESStreamEncryptor_construct(&ptr->enc, aes_key, AESStream_DEFAULT_CLASS);
|
||||
AESStreamDecryptor_construct(&ptr->dec, aes_key, AESStream_DEFAULT_CLASS);
|
||||
ptr->recv_buf = Array_alloc_size(crypto_buffer_size);
|
||||
ptr->send_buf = Array_alloc_size(crypto_buffer_size);
|
||||
ptr->recv_buf = Array_u8_alloc(crypto_buffer_size);
|
||||
ptr->send_buf = Array_u8_alloc(crypto_buffer_size);
|
||||
}
|
||||
|
||||
void EncryptedSocketTCP_destroy(EncryptedSocketTCP* ptr){
|
||||
if(!ptr)
|
||||
return;
|
||||
socket_close(ptr->sock);
|
||||
Array_free(ptr->recv_buf);
|
||||
Array_free(ptr->send_buf);
|
||||
Array_u8_destroy(&ptr->recv_buf);
|
||||
Array_u8_destroy(&ptr->send_buf);
|
||||
}
|
||||
|
||||
void EncryptedSocketTCP_changeKey(EncryptedSocketTCP* ptr, Array(u8) aes_key){
|
||||
@ -42,11 +42,11 @@ Result(void) EncryptedSocketTCP_send(EncryptedSocketTCP* ptr,
|
||||
try_void(
|
||||
socket_send(
|
||||
ptr->sock,
|
||||
Array_sliceTo(ptr->send_buf, encrypted_size)
|
||||
Array_u8_sliceTo(ptr->send_buf, encrypted_size)
|
||||
)
|
||||
);
|
||||
|
||||
// printf("SEND data_size: %u, enc_size: %u\n", buffer.size, encrypted_size);
|
||||
// printf("SEND data_size: %u, enc_size: %u\n", buffer.len, encrypted_size);
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ Result(u32) EncryptedSocketTCP_recv(EncryptedSocketTCP* ptr,
|
||||
{
|
||||
Deferral(1);
|
||||
|
||||
u32 size_to_receive = buffer.size;
|
||||
u32 size_to_receive = buffer.len;
|
||||
if(ptr->dec.block_counter == 0){
|
||||
// There is some metadata at the beginning of AES stream
|
||||
size_to_receive = AESStreamEncryptor_calcDstSize(size_to_receive);
|
||||
@ -63,14 +63,14 @@ Result(u32) EncryptedSocketTCP_recv(EncryptedSocketTCP* ptr,
|
||||
try(i32 received_size, i,
|
||||
socket_recv(
|
||||
ptr->sock,
|
||||
Array_sliceTo(ptr->recv_buf, size_to_receive),
|
||||
Array_u8_sliceTo(ptr->recv_buf, size_to_receive),
|
||||
flags
|
||||
)
|
||||
);
|
||||
try(u32 decrypted_size, u,
|
||||
AESStreamDecryptor_decrypt(
|
||||
&ptr->dec,
|
||||
Array_sliceTo(ptr->recv_buf, received_size),
|
||||
Array_u8_sliceTo(ptr->recv_buf, received_size),
|
||||
buffer
|
||||
)
|
||||
);
|
||||
@ -94,11 +94,11 @@ Result(void) EncryptedSocketTCP_sendRSA(EncryptedSocketTCP* ptr,
|
||||
try_void(
|
||||
socket_send(
|
||||
ptr->sock,
|
||||
Array_sliceTo(ptr->send_buf, encrypted_size)
|
||||
Array_u8_sliceTo(ptr->send_buf, encrypted_size)
|
||||
)
|
||||
);
|
||||
|
||||
// printf("SEND-RSA data_size: %u, enc_size: %u\n", buffer.size, encrypted_size);
|
||||
// printf("SEND-RSA data_size: %u, enc_size: %u\n", buffer.len, encrypted_size);
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -119,30 +119,30 @@ Result(u32) EncryptedSocketTCP_recvRSA(EncryptedSocketTCP* ptr,
|
||||
try(i32 received_size, i,
|
||||
socket_recv(
|
||||
ptr->sock,
|
||||
Array_sliceTo(ptr->recv_buf, size_to_receive),
|
||||
Array_u8_sliceTo(ptr->recv_buf, size_to_receive),
|
||||
flags
|
||||
)
|
||||
);
|
||||
try(u32 decrypted_size, u,
|
||||
RSADecryptor_decrypt(
|
||||
rsa_dec,
|
||||
Array_sliceTo(ptr->recv_buf, received_size)
|
||||
Array_u8_sliceTo(ptr->recv_buf, received_size)
|
||||
)
|
||||
);
|
||||
|
||||
if(fill_whole_buffer){
|
||||
if(decrypted_size != buffer.size){
|
||||
if(decrypted_size != buffer.len){
|
||||
Return RESULT_ERROR_FMT(
|
||||
"SocketRecvFlag_WholeBuffer is set, "
|
||||
"but decrypted_size (%u) != buffer.size (%u)",
|
||||
decrypted_size, buffer.size
|
||||
"but decrypted_size (%u) != buffer.len (%u)",
|
||||
decrypted_size, buffer.len
|
||||
);
|
||||
}
|
||||
}
|
||||
else if(decrypted_size > buffer.size){
|
||||
else if(decrypted_size > buffer.len){
|
||||
Return RESULT_ERROR_FMT(
|
||||
"decrypted_size (%u) > buffer.size (%u)",
|
||||
decrypted_size, buffer.size
|
||||
"decrypted_size (%u) > buffer.len (%u)",
|
||||
decrypted_size, buffer.len
|
||||
);
|
||||
}
|
||||
|
||||
@ -163,16 +163,16 @@ void EncryptedSocketUDP_construct(EncryptedSocketUDP* ptr,
|
||||
ptr->sock = sock;
|
||||
AESBlockEncryptor_construct(&ptr->enc, aes_key, AESBlockEncryptor_DEFAULT_CLASS);
|
||||
AESBlockDecryptor_construct(&ptr->dec, aes_key, AESBlockDecryptor_DEFAULT_CLASS);
|
||||
ptr->recv_buf = Array_alloc_size(crypto_buffer_size);
|
||||
ptr->send_buf = Array_alloc_size(crypto_buffer_size);
|
||||
ptr->recv_buf = Array_u8_alloc(crypto_buffer_size);
|
||||
ptr->send_buf = Array_u8_alloc(crypto_buffer_size);
|
||||
}
|
||||
|
||||
void EncryptedSocketUDP_destroy(EncryptedSocketUDP* ptr){
|
||||
if(!ptr)
|
||||
return;
|
||||
socket_close(ptr->sock);
|
||||
Array_free(ptr->recv_buf);
|
||||
Array_free(ptr->send_buf);
|
||||
Array_u8_destroy(&ptr->recv_buf);
|
||||
Array_u8_destroy(&ptr->send_buf);
|
||||
}
|
||||
|
||||
void EncryptedSocketUDP_changeKey(EncryptedSocketUDP* ptr, Array(u8) aes_key){
|
||||
@ -195,7 +195,7 @@ Result(void) EncryptedSocketUDP_sendto(EncryptedSocketUDP* ptr,
|
||||
try_void(
|
||||
socket_sendto(
|
||||
ptr->sock,
|
||||
Array_sliceTo(ptr->send_buf, encrypted_size),
|
||||
Array_u8_sliceTo(ptr->send_buf, encrypted_size),
|
||||
remote_end
|
||||
)
|
||||
);
|
||||
@ -209,11 +209,11 @@ Result(i32) EncryptedSocketUDP_recvfrom(EncryptedSocketUDP* ptr,
|
||||
Deferral(1);
|
||||
|
||||
// There is some metadata at the start of each AES block
|
||||
u32 size_to_receive = AESBlockEncryptor_calcDstSize(buffer.size);
|
||||
u32 size_to_receive = AESBlockEncryptor_calcDstSize(buffer.len);
|
||||
try(i32 received_size, i,
|
||||
socket_recvfrom(
|
||||
ptr->sock,
|
||||
Array_sliceTo(ptr->recv_buf, size_to_receive),
|
||||
Array_u8_sliceTo(ptr->recv_buf, size_to_receive),
|
||||
flags,
|
||||
remote_end
|
||||
)
|
||||
@ -221,7 +221,7 @@ Result(i32) EncryptedSocketUDP_recvfrom(EncryptedSocketUDP* ptr,
|
||||
try(u32 decrypted_size, u,
|
||||
AESBlockDecryptor_decrypt(
|
||||
&ptr->dec,
|
||||
Array_sliceTo(ptr->recv_buf, received_size),
|
||||
Array_u8_sliceTo(ptr->recv_buf, received_size),
|
||||
buffer
|
||||
)
|
||||
);
|
||||
|
||||
@ -28,14 +28,14 @@ Result(void) EncryptedSocketTCP_send(EncryptedSocketTCP* ptr,
|
||||
|
||||
#define EncryptedSocketTCP_sendStruct(socket, structPtr)\
|
||||
EncryptedSocketTCP_send(socket,\
|
||||
Array_construct_size(structPtr, sizeof(*structPtr)))
|
||||
struct_castTo_Array_u8(structPtr))
|
||||
|
||||
Result(u32) EncryptedSocketTCP_recv(EncryptedSocketTCP* ptr,
|
||||
Array(u8) buffer, SocketRecvFlag flags);
|
||||
|
||||
#define EncryptedSocketTCP_recvStruct(socket, structPtr)\
|
||||
EncryptedSocketTCP_recv(socket,\
|
||||
Array_construct_size(structPtr, sizeof(*structPtr)),\
|
||||
struct_castTo_Array_u8(structPtr),\
|
||||
SocketRecvFlag_WholeBuffer)
|
||||
|
||||
Result(void) EncryptedSocketTCP_sendRSA(EncryptedSocketTCP* ptr,
|
||||
@ -43,14 +43,14 @@ Result(void) EncryptedSocketTCP_sendRSA(EncryptedSocketTCP* ptr,
|
||||
|
||||
#define EncryptedSocketTCP_sendStructRSA(socket, rsa_enc, structPtr)\
|
||||
EncryptedSocketTCP_sendRSA(socket, rsa_enc,\
|
||||
Array_construct_size(structPtr, sizeof(*structPtr)))
|
||||
struct_castTo_Array_u8(structPtr))
|
||||
|
||||
Result(u32) EncryptedSocketTCP_recvRSA(EncryptedSocketTCP* ptr,
|
||||
RSADecryptor* rsa_dec, Array(u8) buffer, SocketRecvFlag flags);
|
||||
|
||||
#define EncryptedSocketTCP_recvStructRSA(socket, rsa_dec, structPtr)\
|
||||
EncryptedSocketTCP_recvRSA(socket, rsa_dec,\
|
||||
Array_construct_size(structPtr, sizeof(*structPtr)),\
|
||||
struct_castTo_Array_u8(structPtr),\
|
||||
SocketRecvFlag_WholeBuffer)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -60,11 +60,11 @@ Result(void) socket_connect(Socket s, EndpointIPv4 remote_end){
|
||||
}
|
||||
|
||||
Result(void) socket_send(Socket s, Array(u8) buffer){
|
||||
i32 r = send(s, buffer.data, buffer.size, 0);
|
||||
i32 r = send(s, (void*)buffer.data, buffer.len, 0);
|
||||
if(r < 0){
|
||||
return RESULT_ERROR_SOCKET();
|
||||
}
|
||||
if((u32)r != buffer.size){
|
||||
if((u32)r != buffer.len){
|
||||
return RESULT_ERROR_FMT("Socket was unable to send data");
|
||||
}
|
||||
return RESULT_VOID;
|
||||
@ -72,11 +72,11 @@ Result(void) socket_send(Socket s, Array(u8) buffer){
|
||||
|
||||
Result(void) socket_sendto(Socket s, Array(u8) buffer, EndpointIPv4 dst){
|
||||
struct sockaddr_in sockaddr = EndpointIPv4_toSockaddr(dst);
|
||||
i32 r = sendto(s, buffer.data, buffer.size, 0, (void*)&sockaddr, sizeof(sockaddr));
|
||||
i32 r = sendto(s, (void*)buffer.data, buffer.len, 0, (void*)&sockaddr, sizeof(sockaddr));
|
||||
if(r < 0){
|
||||
return RESULT_ERROR_SOCKET();
|
||||
}
|
||||
if((u32)r != buffer.size){
|
||||
if((u32)r != buffer.len){
|
||||
return RESULT_ERROR_FMT("Socket was unable to send data");
|
||||
}
|
||||
return RESULT_VOID;
|
||||
@ -92,11 +92,11 @@ static inline int SocketRecvFlags_toStd(SocketRecvFlag flags){
|
||||
}
|
||||
|
||||
Result(i32) socket_recv(Socket s, Array(u8) buffer, SocketRecvFlag flags){
|
||||
i32 r = recv(s, buffer.data, buffer.size, SocketRecvFlags_toStd(flags));
|
||||
i32 r = recv(s, (void*)buffer.data, buffer.len, SocketRecvFlags_toStd(flags));
|
||||
if(r < 0){
|
||||
return RESULT_ERROR_SOCKET();
|
||||
}
|
||||
if(r == 0 || (flags & SocketRecvFlag_WholeBuffer && (u32)r != buffer.size))
|
||||
if(r == 0 || (flags & SocketRecvFlag_WholeBuffer && (u32)r != buffer.len))
|
||||
{
|
||||
return RESULT_ERROR("Socket closed", false);
|
||||
}
|
||||
@ -106,12 +106,12 @@ Result(i32) socket_recv(Socket s, Array(u8) buffer, SocketRecvFlag flags){
|
||||
Result(i32) socket_recvfrom(Socket s, Array(u8) buffer, SocketRecvFlag flags, NULLABLE(EndpointIPv4*) remote_end){
|
||||
struct sockaddr_in remote_addr = {0};
|
||||
i32 sockaddr_size = sizeof(remote_addr);
|
||||
i32 r = recvfrom(s, buffer.data, buffer.size, SocketRecvFlags_toStd(flags),
|
||||
i32 r = recvfrom(s, (void*)buffer.data, buffer.len, SocketRecvFlags_toStd(flags),
|
||||
(struct sockaddr*)&remote_addr, (void*)&sockaddr_size);
|
||||
if(r < 0){
|
||||
return RESULT_ERROR_SOCKET();
|
||||
}
|
||||
if(r == 0 || (flags & SocketRecvFlag_WholeBuffer && (u32)r != buffer.size))
|
||||
if(r == 0 || (flags & SocketRecvFlag_WholeBuffer && (u32)r != buffer.len))
|
||||
{
|
||||
return RESULT_ERROR("Socket closed", false);
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_
|
||||
}
|
||||
|
||||
str validateUsername_str(str username){
|
||||
if(username.size < USERNAME_SIZE_MIN || username.size > USERNAME_SIZE_MAX){
|
||||
if(username.len < USERNAME_SIZE_MIN || username.len > USERNAME_SIZE_MAX){
|
||||
return str_from_cstr(
|
||||
sprintf_malloc(
|
||||
"username length (in bytes) must be >= %i and <= %i\n",
|
||||
@ -25,7 +25,7 @@ str validateUsername_str(str username){
|
||||
);
|
||||
}
|
||||
|
||||
for(u32 i = 0; i < username.size; i++){
|
||||
for(u32 i = 0; i < username.len; i++){
|
||||
char c = username.data[i];
|
||||
if (char_isLatinLower(c) ||
|
||||
char_isLatinUpper(c) ||
|
||||
@ -56,8 +56,8 @@ Result(void) ClientHandshake_tryConstruct(ClientHandshake* ptr, PacketHeader* he
|
||||
_PacketHeader_construct(ClientHandshake);
|
||||
memset(ptr, 0, sizeof(*ptr));
|
||||
|
||||
try_assert(session_key.size == sizeof(ptr->session_key));
|
||||
memcpy(ptr->session_key, session_key.data, session_key.size);
|
||||
try_assert(session_key.len == sizeof(ptr->session_key));
|
||||
memcpy(ptr->session_key, session_key.data, session_key.len);
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
@ -97,10 +97,10 @@ Result(void) LoginRequest_tryConstruct(LoginRequest *ptr, PacketHeader* header,
|
||||
if(name_error_str.data){
|
||||
Return RESULT_ERROR(name_error_str.data, true);
|
||||
}
|
||||
memcpy(ptr->username, username.data, username.size);
|
||||
memcpy(ptr->username, username.data, username.len);
|
||||
|
||||
try_assert(token.size == sizeof(ptr->token));
|
||||
memcpy(ptr->token, token.data, token.size);
|
||||
try_assert(token.len == sizeof(ptr->token));
|
||||
memcpy(ptr->token, token.data, token.len);
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
@ -126,10 +126,10 @@ Result(void) RegisterRequest_tryConstruct(RegisterRequest *ptr, PacketHeader* he
|
||||
if(name_error_str.data){
|
||||
Return RESULT_ERROR(name_error_str.data, true);
|
||||
}
|
||||
memcpy(ptr->username, username.data, username.size);
|
||||
memcpy(ptr->username, username.data, username.len);
|
||||
|
||||
try_assert(token.size == sizeof(ptr->token));
|
||||
memcpy(ptr->token, token.data, token.size);
|
||||
try_assert(token.len == sizeof(ptr->token));
|
||||
memcpy(ptr->token, token.data, token.len);
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ void ClientConnection_close(ClientConnection* conn){
|
||||
if(!conn)
|
||||
return;
|
||||
EncryptedSocketTCP_destroy(&conn->sock);
|
||||
Array_free(conn->session_key);
|
||||
Array_u8_destroy(&conn->session_key);
|
||||
free(conn);
|
||||
}
|
||||
|
||||
@ -22,9 +22,9 @@ Result(ClientConnection*) ClientConnection_accept(ConnectionHandlerArgs* args)
|
||||
conn->client_end = args->client_end;
|
||||
conn->session_id = args->session_id;
|
||||
conn->authorized = false;
|
||||
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
|
||||
conn->session_key = Array_u8_alloc(AES_SESSION_KEY_SIZE);
|
||||
// correct session key will be received from client later
|
||||
Array_memset(conn->session_key, 0);
|
||||
Array_u8_memset(&conn->session_key, 0);
|
||||
EncryptedSocketTCP_construct(&conn->sock, args->accepted_socket_tcp, NETWORK_BUFFER_SIZE, conn->session_key);
|
||||
try_void(socket_TCP_enableAliveChecks_default(args->accepted_socket_tcp));
|
||||
|
||||
@ -44,7 +44,7 @@ Result(ClientConnection*) ClientConnection_accept(ConnectionHandlerArgs* args)
|
||||
try_void(EncryptedSocketTCP_recvStructRSA(&conn->sock, &rsa_dec, &client_handshake));
|
||||
|
||||
// use received session key
|
||||
memcpy(conn->session_key.data, client_handshake.session_key, conn->session_key.size);
|
||||
memcpy(conn->session_key.data, client_handshake.session_key, conn->session_key.len);
|
||||
EncryptedSocketTCP_changeKey(&conn->sock, conn->session_key);
|
||||
|
||||
// send ServerHandshake
|
||||
|
||||
@ -14,10 +14,10 @@ declare_RequestHandler(GetMessageBlock)
|
||||
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
|
||||
|
||||
// send response
|
||||
GetMessageBlockResponse res;
|
||||
GetMessageBlockResponse_construct(&res, res_head, );
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||
// GetMessageBlockResponse res;
|
||||
// GetMessageBlockResponse_construct(&res, res_head, );
|
||||
// try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||
// try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -54,8 +54,8 @@ declare_RequestHandler(Login)
|
||||
u64 user_id = *id_ptr;
|
||||
|
||||
// get user by id
|
||||
try_assert(user_id < List_len(conn->server->users.cache_list, UserInfo));
|
||||
UserInfo* u = &List_index(conn->server->users.cache_list, UserInfo, user_id);
|
||||
try_assert(user_id < conn->server->users.cache_list.len);
|
||||
UserInfo* u = conn->server->users.cache_list.data + user_id;
|
||||
|
||||
// validate token hash
|
||||
if(memcmp(req.token, u->token, sizeof(req.token)) != 0){
|
||||
|
||||
@ -55,7 +55,7 @@ declare_RequestHandler(Register)
|
||||
UserInfo user;
|
||||
memset(&user, 0, sizeof(UserInfo));
|
||||
|
||||
user.name_len = username_str.size;
|
||||
user.name_len = username_str.len;
|
||||
memcpy(user.name, username_str.data, user.name_len);
|
||||
|
||||
memcpy(user.token, req.token, sizeof(req.token));
|
||||
@ -66,8 +66,8 @@ declare_RequestHandler(Register)
|
||||
try(u64 user_id, u,
|
||||
idb_pushRow(conn->server->users.table, &user, false)
|
||||
);
|
||||
try_assert(user_id == List_len(conn->server->users.cache_list, UserInfo));
|
||||
List_pushMany(&conn->server->users.cache_list, UserInfo, &user, 1);
|
||||
try_assert(user_id == conn->server->users.cache_list.len);
|
||||
List_UserInfo_pushMany(&conn->server->users.cache_list, &user, 1);
|
||||
try_assert(HashMap_tryPush(&conn->server->users.username_id_map, username_str, &user_id));
|
||||
|
||||
// manually unlock mutex
|
||||
|
||||
@ -13,13 +13,30 @@ declare_RequestHandler(SendMessage)
|
||||
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
|
||||
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
|
||||
|
||||
if(req.data_size < MESSAGE_SIZE_MIN || req.data_size > MESSAGE_SIZE_MAX){
|
||||
try_void(sendErrorMessage_f(log_ctx, conn, res_head,
|
||||
LogSeverity_Warn,
|
||||
"message size must be >= %i and <= %i",
|
||||
MESSAGE_SIZE_MIN, MESSAGE_SIZE_MAX
|
||||
));
|
||||
// this will close socket connection
|
||||
Return RESULT_ERROR("invalid message size", false);
|
||||
}
|
||||
|
||||
// receive message data
|
||||
Array(u8) message_data = Array_u8_alloc(req.data_size);
|
||||
try_void(EncryptedSocketTCP_recv(&conn->sock, message_data, SocketRecvFlag_WholeBuffer));
|
||||
|
||||
for(u16 i = 0; i < message_data.len; i++){
|
||||
u8 b = message_data.data[i];
|
||||
}
|
||||
|
||||
|
||||
// send response
|
||||
SendMessageResponse res;
|
||||
SendMessageResponse_construct(&res, res_head, );
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||
// SendMessageResponse res;
|
||||
// SendMessageResponse_construct(&res, res_head, );
|
||||
// try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||
// try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -24,16 +24,16 @@ declare_RequestHandler(ServerPublicInfo)
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
case ServerPublicInfo_Name:
|
||||
content = str_castTo_Array(conn->server->name);
|
||||
content = str_castTo_Array_u8(conn->server->name);
|
||||
break;
|
||||
case ServerPublicInfo_Description:
|
||||
content = str_castTo_Array(conn->server->description);
|
||||
content = str_castTo_Array_u8(conn->server->description);
|
||||
break;
|
||||
}
|
||||
|
||||
// send response
|
||||
ServerPublicInfoResponse res;
|
||||
ServerPublicInfoResponse_construct(&res, res_head, content.size);
|
||||
ServerPublicInfoResponse_construct(&res, res_head, content.len);
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||
try_void(EncryptedSocketTCP_send(&conn->sock, content));
|
||||
|
||||
@ -10,16 +10,16 @@ Result(void) sendErrorMessage(
|
||||
Deferral(1);
|
||||
|
||||
//limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
|
||||
if(msg.size > ERROR_MESSAGE_MAX_SIZE)
|
||||
msg.size = ERROR_MESSAGE_MAX_SIZE;
|
||||
if(msg.len > ERROR_MESSAGE_MAX_SIZE)
|
||||
msg.len = ERROR_MESSAGE_MAX_SIZE;
|
||||
|
||||
log(log_severity, log_ctx, FMT_str, msg.size, msg.data);
|
||||
log(log_severity, log_ctx, FMT_str, msg.len, msg.data);
|
||||
|
||||
ErrorMessage res;
|
||||
ErrorMessage_construct(&res, res_head, msg.size);
|
||||
ErrorMessage_construct(&res, res_head, msg.len);
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||
try_void(EncryptedSocketTCP_send(&conn->sock, str_castTo_Array(msg)));
|
||||
try_void(EncryptedSocketTCP_send(&conn->sock, str_castTo_Array_u8(msg)));
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -21,10 +21,10 @@ void Server_free(Server* self){
|
||||
|
||||
idb_close(self->db);
|
||||
|
||||
List_destroy(&self->users.cache_list);
|
||||
List_UserInfo_destroy(&self->users.cache_list);
|
||||
HashMap_destroy(&self->users.username_id_map);
|
||||
|
||||
List_destroy(&self->messages.blocks_meta_list);
|
||||
List_MessageBlockMeta_destroy(&self->messages.blocks_meta_list);
|
||||
LList_MessageBlock_destroy(&self->messages.blocks_queue);
|
||||
free(self->messages.incomplete_block);
|
||||
|
||||
@ -86,9 +86,9 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu
|
||||
|
||||
// parse db_aes_key
|
||||
try_void(config_findValue(config_str, STR("db_aes_key"), &tmp_str, true));
|
||||
Array(u8) db_aes_key = Array_alloc_size(base64_decodedSize(tmp_str.data, tmp_str.size));
|
||||
Array(u8) db_aes_key = Array_u8_alloc(base64_decodedSize(tmp_str.data, tmp_str.len));
|
||||
Defer(free(db_aes_key.data));
|
||||
base64_decode(tmp_str.data, tmp_str.size, db_aes_key.data);
|
||||
base64_decode(tmp_str.data, tmp_str.len, db_aes_key.data);
|
||||
|
||||
// parse db_dir and open db
|
||||
try_void(config_findValue(config_str, STR("db_dir"), &tmp_str, true));
|
||||
@ -102,17 +102,17 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu
|
||||
|
||||
// load whole users table to list
|
||||
try_void(
|
||||
idb_createListFromTable(self->users.table, &self->users.cache_list, false)
|
||||
idb_createListFromTable(self->users.table, (void*)&self->users.cache_list, false)
|
||||
);
|
||||
|
||||
// build name-id map
|
||||
try(u64 users_count, u, idb_getRowCount(self->users.table, false));
|
||||
HashMap_construct(&self->users.username_id_map, u64, NULL);
|
||||
for(u64 id = 0; id < users_count; id++){
|
||||
UserInfo* row = &List_index(self->users.cache_list, UserInfo, id);
|
||||
str key = str_construct(row->name, row->name_len, true);
|
||||
UserInfo* user = self->users.cache_list.data + id;
|
||||
str key = str_construct(user->name, user->name_len, true);
|
||||
if(!HashMap_tryPush(&self->users.username_id_map, key, &id)){
|
||||
Return RESULT_ERROR_FMT("duplicate user name '"FMT_str"'", key.size, key.data);
|
||||
Return RESULT_ERROR_FMT("duplicate user name '"FMT_str"'", key.len, key.data);
|
||||
}
|
||||
}
|
||||
logDebug(log_ctx, "loaded "FMT_u64" users", users_count);
|
||||
@ -129,7 +129,7 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu
|
||||
|
||||
// load whole message_blocks_meta table to list
|
||||
try_void(
|
||||
idb_createListFromTable(self->messages.blocks_meta_table, &self->messages.blocks_meta_list, false)
|
||||
idb_createListFromTable(self->messages.blocks_meta_table, (void*)&self->messages.blocks_meta_list, false)
|
||||
);
|
||||
|
||||
// load N last blocks to the queue
|
||||
@ -148,6 +148,7 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu
|
||||
);
|
||||
try_void(idb_getRow(self->messages.blocks_table, id, node->value.data, false));
|
||||
}
|
||||
logDebug(log_ctx, "loaded "FMT_u64" message blocks", message_blocks_count);
|
||||
|
||||
success = true;
|
||||
Return RESULT_VALUE(p, self);
|
||||
@ -199,7 +200,7 @@ static void* handleConnection(void* _args){
|
||||
if(r.error){
|
||||
Error_addCallPos(r.error, ErrorCallPos_here());
|
||||
str e_str = Error_toStr(r.error);
|
||||
logError(log_ctx, FMT_str, e_str.size, e_str.data);
|
||||
logError(log_ctx, FMT_str, e_str.len, e_str.data);
|
||||
str_free(e_str);
|
||||
Error_free(r.error);
|
||||
}
|
||||
@ -213,6 +214,7 @@ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_c
|
||||
Deferral(16);
|
||||
|
||||
Server* server = args->server;
|
||||
logInfo(log_ctx, "a client is trying to connect");
|
||||
ClientConnection* conn = NULL;
|
||||
// establish encrypted connection
|
||||
try(conn, p, ClientConnection_accept(args));
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
|
||||
typedef struct ClientConnection ClientConnection;
|
||||
|
||||
List_declare(UserInfo);
|
||||
List_declare(MessageBlockMeta);
|
||||
LList_declare(MessageBlock);
|
||||
|
||||
#define MESSAGE_BLOCKS_CACHE_COUNT 50
|
||||
|
||||
Loading…
Reference in New Issue
Block a user