finished ClientCredential_create
This commit is contained in:
parent
37f38feec7
commit
4fda6ae9e8
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "tlibc/errors.h"
|
|
||||||
|
|
||||||
Result(void) client_run();
|
|
||||||
Result(void) server_run(cstr server_endpoint_str);
|
|
||||||
209
src/client.c
209
src/client.c
@ -1,209 +0,0 @@
|
|||||||
#include "chat.h"
|
|
||||||
#include <readline/readline.h>
|
|
||||||
#include <readline/history.h>
|
|
||||||
#include "term.h"
|
|
||||||
#include "network/socket.h"
|
|
||||||
#include "cryptography/cryptography.h"
|
|
||||||
#include "tlibc/string/StringBuilder.h"
|
|
||||||
|
|
||||||
static const str greeting_art = STR(
|
|
||||||
" ^,,^ ╱|\n"
|
|
||||||
" ( •·•) Meum! (o.o`7\n"
|
|
||||||
" / ` | Meum... |`˜ \\\n"
|
|
||||||
"\\(_,J J L l`,)/\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
static const str farewell_art = STR(
|
|
||||||
" ^,,^ ╱|\n"
|
|
||||||
" ( -.-) (>,<`7\n"
|
|
||||||
" / ` | Goodbye! |`˜ \\\n"
|
|
||||||
"\\(_,J J L l`,)/\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
static Result(void) commandExec(str command, bool* stop);
|
|
||||||
|
|
||||||
typedef struct ClientCredential {
|
|
||||||
str username;
|
|
||||||
u8 passhash_lvl2[password_hash_size];
|
|
||||||
EncryptorAES aes_enc;
|
|
||||||
DecryptorAES aes_dec;
|
|
||||||
EncryptorRSA rsa_enc;
|
|
||||||
DecryptorRSA rsa_dec;
|
|
||||||
} ClientCredential;
|
|
||||||
|
|
||||||
typedef struct ServerConnection {
|
|
||||||
EndpointIPv4 server_end;
|
|
||||||
Socket system_socket;
|
|
||||||
Socket content_socket;
|
|
||||||
EncryptorRSA rsa_enc;
|
|
||||||
EncryptorAES session_aes_enc;
|
|
||||||
DecryptorAES session_aes_dec;
|
|
||||||
} ServerConnection;
|
|
||||||
|
|
||||||
Result(ServerConnection*) connectToServer(EndpointIPv4 server_end, str server_key);
|
|
||||||
|
|
||||||
Result(void) client_run() {
|
|
||||||
Deferral(32);
|
|
||||||
if(!term_init()){
|
|
||||||
Return RESULT_ERROR("can't init terminal", false);
|
|
||||||
}
|
|
||||||
using_history();
|
|
||||||
|
|
||||||
fputs(greeting_art.data, stdout);
|
|
||||||
|
|
||||||
char* command_input_prev = NULL;
|
|
||||||
char* command_input_raw = NULL;
|
|
||||||
Defer(rl_free(command_input_prev));
|
|
||||||
str command_input = str_null;
|
|
||||||
bool stop = false;
|
|
||||||
while((command_input_raw = readline("> ")) && !stop){
|
|
||||||
rl_free(command_input_prev);
|
|
||||||
command_input_prev = command_input_raw;
|
|
||||||
command_input = str_from_cstr(command_input_raw);
|
|
||||||
str_trim(&command_input, true);
|
|
||||||
if(command_input.size == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
add_history(command_input.data);
|
|
||||||
Result(void) com_result = commandExec(command_input, &stop);
|
|
||||||
if(com_result.error){
|
|
||||||
str e_str = Error_toStr(com_result.error);
|
|
||||||
printfe("%s\n", e_str.data);
|
|
||||||
free(e_str.data);
|
|
||||||
Error_free(com_result.error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define is_alias(LITERAL) str_equals(command, STR(LITERAL))
|
|
||||||
|
|
||||||
static ClientCredential* client_credential = NULL;
|
|
||||||
|
|
||||||
static Result(void) commandExec(str command, bool* stop){
|
|
||||||
Deferral(64);
|
|
||||||
char answer_buf[512];
|
|
||||||
const u32 answer_buf_size = sizeof(answer_buf);
|
|
||||||
if(is_alias("q") || is_alias("quit") || is_alias("exit")){
|
|
||||||
fputs(farewell_art.data, stdout);
|
|
||||||
*stop = true;
|
|
||||||
}
|
|
||||||
else if(is_alias("clear")){
|
|
||||||
term_clear();
|
|
||||||
}
|
|
||||||
else if(is_alias("h") || is_alias("help")){
|
|
||||||
puts(
|
|
||||||
"COMMANDS:\n"
|
|
||||||
"q, quit, exit Close the program.\n"
|
|
||||||
"clear Clear the screen.\n"
|
|
||||||
"j, join Join a server.\n"
|
|
||||||
"c, connect Connect to a server you joined.\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (is_alias("j") || is_alias("join")){
|
|
||||||
puts("Enter server address (ip:port): ");
|
|
||||||
fgets(answer_buf, answer_buf_size, stdin);
|
|
||||||
EndpointIPv4 new_server_end;
|
|
||||||
try_void(EndpointIPv4_parse(answer_buf, &new_server_end));
|
|
||||||
puts("Enter server key (): ");
|
|
||||||
fgets(answer_buf, answer_buf_size, stdin);
|
|
||||||
str new_server_key = str_from_cstr(answer_buf);
|
|
||||||
try(ServerConnection* conn, p, connectToServer(new_server_end, new_server_key));
|
|
||||||
}
|
|
||||||
else if(is_alias("c") || is_alias("connect")){
|
|
||||||
// TODO: read saved servers from database
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Return RESULT_ERROR_FMT("unknown kommand: '%s'\n"
|
|
||||||
"Use 'h' to see list of avaliable commands\n",
|
|
||||||
command.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
Return RESULT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientCredential_free(ClientCredential* cred){
|
|
||||||
if(cred == NULL)
|
|
||||||
return;
|
|
||||||
free(cred->username.data);
|
|
||||||
free(cred);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define __passhash_lvl_iter 1e5
|
|
||||||
|
|
||||||
Result(ClientCredential*) ClientCredential_create(str username, str password){
|
|
||||||
Deferral(32);
|
|
||||||
ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential));
|
|
||||||
memset(cred, 0, sizeof(ClientCredential));
|
|
||||||
bool success = false;
|
|
||||||
Defer(
|
|
||||||
if(!success)
|
|
||||||
ClientCredential_free(cred);
|
|
||||||
);
|
|
||||||
|
|
||||||
cred->username = str_copy(username);
|
|
||||||
|
|
||||||
// concat password and username
|
|
||||||
StringBuilder sb = StringBuilder_alloc(username.size + password.size + 1);
|
|
||||||
Defer(StringBuilder_destroy(&sb));
|
|
||||||
StringBuilder_append_str(&sb, password);
|
|
||||||
StringBuilder_append_str(&sb, username);
|
|
||||||
|
|
||||||
// lvl 1 hash - is being used to generate rsa keys
|
|
||||||
u8 passhash_lvl1[password_hash_size];
|
|
||||||
hash_password(StringBuilder_getStr(&sb), passhash_lvl1, __passhash_lvl_iter);
|
|
||||||
// lvl 2 hash - is being used to authorize client on server
|
|
||||||
str _passhash_lvl1_str = str_construct((void*)passhash_lvl1, password_hash_size, false);
|
|
||||||
hash_password(_passhash_lvl1_str, cred->passhash_lvl2, __passhash_lvl_iter);
|
|
||||||
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
return RESULT_VALUE(p, cred);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerConnection_close(ServerConnection* conn){
|
|
||||||
if(conn == NULL)
|
|
||||||
return;
|
|
||||||
socket_close(conn->system_socket);
|
|
||||||
socket_close(conn->content_socket);
|
|
||||||
free(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result(ServerConnection*) connectToServer(EndpointIPv4 server_end, str server_key){
|
|
||||||
Deferral(64);
|
|
||||||
if(client_credential == NULL){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
str end_str = EndpointIPv4_toStr(server_end);
|
|
||||||
Defer(free(end_str.data));
|
|
||||||
if(EndpointIPv4_is_invalid(server_end)){
|
|
||||||
Return RESULT_ERROR_FMT("endpoint is invalid: %s", end_str.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerConnection* conn = (ServerConnection*)malloc(sizeof(ServerConnection));
|
|
||||||
memset(conn, 0, sizeof(ServerConnection));
|
|
||||||
bool success = false;
|
|
||||||
Defer(
|
|
||||||
if(!success)
|
|
||||||
ServerConnection_close(conn);
|
|
||||||
);
|
|
||||||
|
|
||||||
printf("connecting to server %s\n", end_str.data);
|
|
||||||
try(conn->system_socket, i, socket_open_TCP());
|
|
||||||
try_void(socket_connect(conn->system_socket, server_end));
|
|
||||||
|
|
||||||
// ask user name and password
|
|
||||||
// calculate key pair from password hash
|
|
||||||
// send client public key to server
|
|
||||||
// request server info
|
|
||||||
// show server info
|
|
||||||
// save server info to user's db
|
|
||||||
// hash password more times
|
|
||||||
// request log in
|
|
||||||
// if not registered, request registration and then log in
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
Return RESULT_VALUE(p, conn);
|
|
||||||
}
|
|
||||||
74
src/client/ClientCredential.c
Normal file
74
src/client/ClientCredential.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "client.h"
|
||||||
|
#include "tlibc/string/StringBuilder.h"
|
||||||
|
|
||||||
|
void ClientCredential_free(ClientCredential* cred){
|
||||||
|
if(cred == NULL)
|
||||||
|
return;
|
||||||
|
free(cred->username.data);
|
||||||
|
free(cred->aes_key.data);
|
||||||
|
free(cred->token.data);
|
||||||
|
RSA_destroyPrivateKey(&cred->sk);
|
||||||
|
RSA_destroyPublicKey(&cred->pk);
|
||||||
|
free(cred);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __passhash_lvl_iter 1e5
|
||||||
|
|
||||||
|
Result(ClientCredential*) ClientCredential_create(str username, str password){
|
||||||
|
Deferral(32);
|
||||||
|
ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential));
|
||||||
|
memset(cred, 0, sizeof(ClientCredential));
|
||||||
|
bool success = false;
|
||||||
|
Defer(
|
||||||
|
if(!success)
|
||||||
|
free(cred);
|
||||||
|
);
|
||||||
|
|
||||||
|
cred->username = str_copy(username);
|
||||||
|
Defer(
|
||||||
|
if(!success)
|
||||||
|
free(cred->username.data);
|
||||||
|
);
|
||||||
|
|
||||||
|
// concat password and username
|
||||||
|
StringBuilder sb = StringBuilder_alloc(username.size + password.size + 1);
|
||||||
|
Defer(StringBuilder_destroy(&sb));
|
||||||
|
StringBuilder_append_str(&sb, password);
|
||||||
|
StringBuilder_append_str(&sb, username);
|
||||||
|
Array(u8) password_and_username = str_castTo_Array(StringBuilder_getStr(&sb));
|
||||||
|
// lvl 1 hash - is used to generate RSA keys
|
||||||
|
Array(u8) passhash_lvl1 = Array_alloc(u8, password_hash_size);
|
||||||
|
cred->aes_key = Array_alloc(u8, password_hash_size);
|
||||||
|
cred->token = Array_alloc(u8, password_hash_size);
|
||||||
|
Defer(
|
||||||
|
free(passhash_lvl1.data);
|
||||||
|
if(!success){
|
||||||
|
free(cred->aes_key.data);
|
||||||
|
free(cred->token.data);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
hash_password(password_and_username, passhash_lvl1.data, __passhash_lvl_iter);
|
||||||
|
// lvl 2 hash - is used as AES key
|
||||||
|
hash_password(passhash_lvl1, cred->aes_key.data, __passhash_lvl_iter);
|
||||||
|
// lvl 3 hash - is used to authorize client on server
|
||||||
|
hash_password(cred->aes_key, cred->token.data, __passhash_lvl_iter);
|
||||||
|
|
||||||
|
// generate client rsa keys from password hash
|
||||||
|
br_hmac_drbg_context passhash_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||||
|
br_hmac_drbg_init(&passhash_based_rng, &br_sha256_vtable, passhash_lvl1.data, password_hash_size);
|
||||||
|
try_void(RSA_generateKeyPair(4096, &cred->sk, &cred->pk, &passhash_based_rng.vtable));
|
||||||
|
Defer(
|
||||||
|
if(!success){
|
||||||
|
RSA_destroyPrivateKey(&cred->sk);
|
||||||
|
RSA_destroyPublicKey(&cred->pk);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
DecryptorRSA_construct(&cred->rsa_dec, &cred->sk);
|
||||||
|
EncryptorRSA_construct(&cred->rsa_enc, &cred->pk);
|
||||||
|
DecryptorAES_construct(&cred->aes_dec, cred->aes_key);
|
||||||
|
EncryptorAES_construct(&cred->aes_enc, cred->aes_key);
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
Return RESULT_VALUE(p, cred);
|
||||||
|
}
|
||||||
44
src/client/ServerConnection.c
Normal file
44
src/client/ServerConnection.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
void ServerConnection_close(ServerConnection* conn){
|
||||||
|
if(conn == NULL)
|
||||||
|
return;
|
||||||
|
socket_close(conn->system_socket);
|
||||||
|
socket_close(conn->content_socket);
|
||||||
|
free(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credential, EndpointIPv4 server_end, str server_key){
|
||||||
|
Deferral(64);
|
||||||
|
|
||||||
|
str end_str = EndpointIPv4_toStr(server_end);
|
||||||
|
Defer(free(end_str.data));
|
||||||
|
if(EndpointIPv4_is_invalid(server_end)){
|
||||||
|
Return RESULT_ERROR_FMT("endpoint is invalid: %s", end_str.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerConnection* conn = (ServerConnection*)malloc(sizeof(ServerConnection));
|
||||||
|
memset(conn, 0, sizeof(ServerConnection));
|
||||||
|
bool success = false;
|
||||||
|
Defer(
|
||||||
|
if(!success)
|
||||||
|
ServerConnection_close(conn);
|
||||||
|
);
|
||||||
|
|
||||||
|
printf("connecting to server %s\n", end_str.data);
|
||||||
|
try(conn->system_socket, i, socket_open_TCP());
|
||||||
|
try_void(socket_connect(conn->system_socket, server_end));
|
||||||
|
|
||||||
|
// ask user name and password
|
||||||
|
// calculate key pair from password hash
|
||||||
|
// send client public key to server
|
||||||
|
// request server info
|
||||||
|
// show server info
|
||||||
|
// save server info to user's db
|
||||||
|
// hash password more times
|
||||||
|
// request log in
|
||||||
|
// if not registered, request registration and then log in
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
Return RESULT_VALUE(p, conn);
|
||||||
|
}
|
||||||
118
src/client/client.c
Normal file
118
src/client/client.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// readline.h doesn't include stdio.h
|
||||||
|
// This bug is older than me)))
|
||||||
|
#include "client.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#include <readline/history.h>
|
||||||
|
#include "term.h"
|
||||||
|
|
||||||
|
static const str greeting_art = STR(
|
||||||
|
" ^,,^ ╱|\n"
|
||||||
|
" ( •·•) Meum! (o.o`7\n"
|
||||||
|
" / ` | Meum... |`˜ \\\n"
|
||||||
|
"\\(_,J J L l`,)/\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
static const str farewell_art = STR(
|
||||||
|
" ^,,^ ╱|\n"
|
||||||
|
" ( -.-) (>,<`7\n"
|
||||||
|
" / ` | Goodbye! |`˜ \\\n"
|
||||||
|
"\\(_,J J L l`,)/\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
static ClientCredential* client_credential = NULL;
|
||||||
|
|
||||||
|
static Result(void) commandExec(str command, bool* stop);
|
||||||
|
|
||||||
|
static Result(void) askUserNameAndPassword(ClientCredential** cred){
|
||||||
|
Deferral(8);
|
||||||
|
char username[1024];
|
||||||
|
char password[1024];
|
||||||
|
scanf("username: %s", username);
|
||||||
|
scanf("password: %s", password);
|
||||||
|
try(*cred, p, ClientCredential_create(str_from_cstr(username), str_from_cstr(password)));
|
||||||
|
Return RESULT_VOID;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result(void) client_run() {
|
||||||
|
Deferral(32);
|
||||||
|
if(!term_init()){
|
||||||
|
Return RESULT_ERROR("can't init terminal", false);
|
||||||
|
}
|
||||||
|
using_history();
|
||||||
|
|
||||||
|
fputs(greeting_art.data, stdout);
|
||||||
|
try_void(askUserNameAndPassword(&client_credential));
|
||||||
|
|
||||||
|
char* command_input_prev = NULL;
|
||||||
|
char* command_input_raw = NULL;
|
||||||
|
Defer(rl_free(command_input_prev));
|
||||||
|
str command_input = str_null;
|
||||||
|
bool stop = false;
|
||||||
|
while((command_input_raw = readline("> ")) && !stop){
|
||||||
|
rl_free(command_input_prev);
|
||||||
|
command_input_prev = command_input_raw;
|
||||||
|
command_input = str_from_cstr(command_input_raw);
|
||||||
|
str_trim(&command_input, true);
|
||||||
|
if(command_input.size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
add_history(command_input.data);
|
||||||
|
Result(void) com_result = commandExec(command_input, &stop);
|
||||||
|
if(com_result.error){
|
||||||
|
str e_str = Error_toStr(com_result.error);
|
||||||
|
printfe("%s\n", e_str.data);
|
||||||
|
free(e_str.data);
|
||||||
|
Error_free(com_result.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientCredential_free(client_credential);
|
||||||
|
Return RESULT_VOID;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define is_alias(LITERAL) str_equals(command, STR(LITERAL))
|
||||||
|
|
||||||
|
static Result(void) commandExec(str command, bool* stop){
|
||||||
|
Deferral(64);
|
||||||
|
char answer_buf[512];
|
||||||
|
const u32 answer_buf_size = sizeof(answer_buf);
|
||||||
|
if(is_alias("q") || is_alias("quit") || is_alias("exit")){
|
||||||
|
fputs(farewell_art.data, stdout);
|
||||||
|
*stop = true;
|
||||||
|
}
|
||||||
|
else if(is_alias("clear")){
|
||||||
|
term_clear();
|
||||||
|
}
|
||||||
|
else if(is_alias("h") || is_alias("help")){
|
||||||
|
puts(
|
||||||
|
"COMMANDS:\n"
|
||||||
|
"q, quit, exit Close the program.\n"
|
||||||
|
"clear Clear the screen.\n"
|
||||||
|
"j, join Join a server.\n"
|
||||||
|
"c, connect Connect to a server you joined.\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (is_alias("j") || is_alias("join")){
|
||||||
|
puts("Enter server address (ip:port): ");
|
||||||
|
fgets(answer_buf, answer_buf_size, stdin);
|
||||||
|
EndpointIPv4 new_server_end;
|
||||||
|
try_void(EndpointIPv4_parse(answer_buf, &new_server_end));
|
||||||
|
puts("Enter server key (): ");
|
||||||
|
fgets(answer_buf, answer_buf_size, stdin);
|
||||||
|
str new_server_key = str_from_cstr(answer_buf);
|
||||||
|
try(ServerConnection* conn, p, ServerConnection_open(client_credential, new_server_end, new_server_key));
|
||||||
|
// TODO: close server connection somewhere
|
||||||
|
}
|
||||||
|
else if(is_alias("c") || is_alias("connect")){
|
||||||
|
// TODO: read saved servers from database
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Return RESULT_ERROR_FMT("unknown kommand: '%s'\n"
|
||||||
|
"Use 'h' to see list of avaliable commands\n",
|
||||||
|
command.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return RESULT_VOID;
|
||||||
|
}
|
||||||
|
|
||||||
32
src/client/client.h
Normal file
32
src/client/client.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "network/socket.h"
|
||||||
|
#include "cryptography/cryptography.h"
|
||||||
|
|
||||||
|
Result(void) client_run();
|
||||||
|
|
||||||
|
typedef struct ClientCredential {
|
||||||
|
str username;
|
||||||
|
Array(u8) aes_key;
|
||||||
|
Array(u8) token;
|
||||||
|
br_rsa_private_key sk;
|
||||||
|
br_rsa_public_key pk;
|
||||||
|
EncryptorRSA rsa_enc;
|
||||||
|
DecryptorRSA rsa_dec;
|
||||||
|
EncryptorAES aes_enc;
|
||||||
|
DecryptorAES aes_dec;
|
||||||
|
} ClientCredential;
|
||||||
|
|
||||||
|
Result(ClientCredential*) ClientCredential_create(str username, str password);
|
||||||
|
void ClientCredential_free(ClientCredential* cred);
|
||||||
|
|
||||||
|
typedef struct ServerConnection {
|
||||||
|
EndpointIPv4 server_end;
|
||||||
|
Socket system_socket;
|
||||||
|
Socket content_socket;
|
||||||
|
EncryptorRSA rsa_enc;
|
||||||
|
EncryptorAES session_aes_enc;
|
||||||
|
DecryptorAES session_aes_dec;
|
||||||
|
} ServerConnection;
|
||||||
|
|
||||||
|
Result(ServerConnection*) ServerConnection_open(ClientCredential* client_credential, EndpointIPv4 server_end, str server_key);
|
||||||
|
void ServerConnection_close(ServerConnection* conn);
|
||||||
@ -3,11 +3,12 @@
|
|||||||
|
|
||||||
//TODO: use AES CTR encryption instead of my own padding algorithm
|
//TODO: use AES CTR encryption instead of my own padding algorithm
|
||||||
|
|
||||||
void EncryptorAES_init(EncryptorAES* ptr, Array(u8) key){
|
void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key){
|
||||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||||
|
|
||||||
br_aes_ct64_cbcenc_init(&ptr->enc_ctx, key.data, key.size);
|
br_aes_ct64_cbcenc_init(&ptr->enc_ctx, key.data, key.size);
|
||||||
rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &ptr->rng_ctx.vtable);
|
ptr->rng_ctx.vtable = &br_hmac_drbg_vtable;
|
||||||
|
rng_init_sha256_seedFromTime(&ptr->rng_ctx.vtable);
|
||||||
|
|
||||||
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
memset(ptr->buf, 0, __AES_BUFFER_SIZE);
|
||||||
memset(ptr->iv, 0, sizeof(ptr->iv));
|
memset(ptr->iv, 0, sizeof(ptr->iv));
|
||||||
@ -49,7 +50,7 @@ void EncryptorAES_encrypt(EncryptorAES* ptr, Array(u8) src, Array(u8) dst){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DecryptorAES_init(DecryptorAES* ptr, Array(u8) key){
|
void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key){
|
||||||
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
assert(key.size == 16 || key.size == 24 || key.size == 32);
|
||||||
|
|
||||||
br_aes_ct64_cbcdec_init(&ptr->dec_ctx, key.data, key.size);
|
br_aes_ct64_cbcdec_init(&ptr->dec_ctx, key.data, key.size);
|
||||||
|
|||||||
@ -6,14 +6,32 @@
|
|||||||
// https://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537
|
// https://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537
|
||||||
#define DEFAULT_PUBLIC_EXPONENT 65537
|
#define DEFAULT_PUBLIC_EXPONENT 65537
|
||||||
|
|
||||||
bool RSA_generateKeyPair(u32 key_size, br_rsa_private_key* sk, br_rsa_public_key* pk){
|
Result(void) RSA_generateKeyPair(u32 key_size,
|
||||||
br_hmac_drbg_context rng_ctx;
|
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
||||||
const br_prng_class** rng_class_ptr = &rng_ctx.vtable;
|
const br_prng_class** rng_vtable_ptr)
|
||||||
rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, rng_class_ptr);
|
{
|
||||||
|
Deferral(16);
|
||||||
|
bool success = false;
|
||||||
|
rng_init_sha256_seedFromTime(rng_vtable_ptr);
|
||||||
|
|
||||||
void* sk_buf = malloc(BR_RSA_KBUF_PRIV_SIZE(key_size));
|
void* sk_buf = malloc(BR_RSA_KBUF_PRIV_SIZE(key_size));
|
||||||
|
Defer(
|
||||||
|
if(!success)
|
||||||
|
free(sk_buf)
|
||||||
|
);
|
||||||
|
|
||||||
void* pk_buf = malloc(BR_RSA_KBUF_PUB_SIZE(key_size));
|
void* pk_buf = malloc(BR_RSA_KBUF_PUB_SIZE(key_size));
|
||||||
u32 r = br_rsa_i31_keygen(rng_class_ptr, sk, sk_buf, pk, pk_buf, key_size, DEFAULT_PUBLIC_EXPONENT);
|
Defer(
|
||||||
return r;
|
if(!success)
|
||||||
|
free(pk_buf)
|
||||||
|
);
|
||||||
|
|
||||||
|
success = br_rsa_i31_keygen(rng_vtable_ptr, sk, sk_buf, pk, pk_buf, key_size, DEFAULT_PUBLIC_EXPONENT);
|
||||||
|
if(!success){
|
||||||
|
Return RESULT_ERROR("br_rsa_i31_keygen() failed", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return RESULT_VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result(void) RSA_computePublicKey(const br_rsa_private_key* sk, br_rsa_public_key* pk){
|
Result(void) RSA_computePublicKey(const br_rsa_private_key* sk, br_rsa_public_key* pk){
|
||||||
@ -162,7 +180,8 @@ Result(void) RSA_parsePrivateKey_DER(Array(u8) _src, br_rsa_private_key* sk){
|
|||||||
|
|
||||||
void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk){
|
void EncryptorRSA_construct(EncryptorRSA* ptr, const br_rsa_public_key* pk){
|
||||||
ptr->pk = pk;
|
ptr->pk = pk;
|
||||||
rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &ptr->rng.vtable);
|
ptr->rng.vtable = &br_hmac_drbg_vtable;
|
||||||
|
rng_init_sha256_seedFromTime(&ptr->rng.vtable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size){
|
void EncryptorRSA_encrypt(EncryptorRSA* ptr, Array(u8) src, Array(u8) dst, u32* encrypted_size){
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
/// @param password some byte array
|
/// @param password some byte array
|
||||||
/// @param out_buffer u8[password_hash_size]
|
/// @param out_buffer u8[password_hash_size]
|
||||||
/// @param iterations number of iterations
|
/// @param iterations number of iterations
|
||||||
void hash_password(str password, u8* out_buffer, i32 iterations);
|
void hash_password(Array(u8) password, u8* out_buffer, i32 iterations);
|
||||||
#define password_hash_size 32
|
#define password_hash_size 32
|
||||||
|
|
||||||
|
|
||||||
@ -24,14 +24,13 @@ void hash_password(str password, u8* out_buffer, i32 iterations);
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// @brief Initialize prng context with sha256 hashing algorithm and seed from CLOCK_REALTIME.
|
/// @brief Initialize prng context with sha256 hashing algorithm and seed from CLOCK_REALTIME.
|
||||||
/// @param rng_class pointer to static vtable variable
|
/// @param rng_vtable_ptr pointer to vtable field in prng context. The field must be initialized.
|
||||||
/// @param rng_ctx pointer to vtable field in prng context
|
|
||||||
/// EXAMPLE:
|
/// EXAMPLE:
|
||||||
/// ```
|
/// ```
|
||||||
/// br_hmac_drbg_context rng_ctx;
|
/// br_hmac_drbg_context rng_ctx = { .vtable = &br_hmac_drbg_vtable };
|
||||||
/// rng_init_sha256_seedFromTime(&br_hmac_drbg_vtable, &rng_ctx.vtable);
|
/// rng_init_sha256_seedFromTime(&rng_ctx.vtable);
|
||||||
/// ```
|
/// ```
|
||||||
void rng_init_sha256_seedFromTime(const br_prng_class* rng_class, const br_prng_class** rng_ctx);
|
void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr);
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -57,7 +56,7 @@ typedef struct EncryptorAES {
|
|||||||
} EncryptorAES;
|
} EncryptorAES;
|
||||||
|
|
||||||
/// @param key Array<u8, 16 | 24 | 32>
|
/// @param key Array<u8, 16 | 24 | 32>
|
||||||
void EncryptorAES_init(EncryptorAES* ptr, Array(u8) key);
|
void EncryptorAES_construct(EncryptorAES* ptr, Array(u8) key);
|
||||||
|
|
||||||
/// @brief Encrypts `src` and writes output to `dst`.
|
/// @brief Encrypts `src` and writes output to `dst`.
|
||||||
/// @param src array of any size
|
/// @param src array of any size
|
||||||
@ -74,7 +73,7 @@ typedef struct DecryptorAES {
|
|||||||
} DecryptorAES;
|
} DecryptorAES;
|
||||||
|
|
||||||
/// @param key Array<u8, 16 | 24 | 32>
|
/// @param key Array<u8, 16 | 24 | 32>
|
||||||
void DecryptorAES_init(DecryptorAES* ptr, Array(u8) key);
|
void DecryptorAES_construct(DecryptorAES* ptr, Array(u8) key);
|
||||||
|
|
||||||
/// @brief Decrypts `src` and writes output to `dst`.
|
/// @brief Decrypts `src` and writes output to `dst`.
|
||||||
/// @param src array of any size
|
/// @param src array of any size
|
||||||
@ -91,8 +90,10 @@ void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32*
|
|||||||
/// @param key_size size of public key in bits (2048/3072/4096)
|
/// @param key_size size of public key in bits (2048/3072/4096)
|
||||||
/// @param sk key for decryption
|
/// @param sk key for decryption
|
||||||
/// @param pk key for encryption
|
/// @param pk key for encryption
|
||||||
/// @return true on success
|
/// @param rng_vtable_ptr pointer to vtable field in prng context. The context must be initialized
|
||||||
bool RSA_generateKeyPair(u32 key_size, br_rsa_private_key* sk, br_rsa_public_key* pk);
|
Result(void) RSA_generateKeyPair(u32 key_size,
|
||||||
|
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
||||||
|
const br_prng_class** rng_vtable_ptr);
|
||||||
|
|
||||||
static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){
|
static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){
|
||||||
free(sk->p);
|
free(sk->p);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#include "bearssl_hash.h"
|
#include "bearssl_hash.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
void hash_password(str password, u8* out_buffer, i32 iterations){
|
void hash_password(Array(u8) password, u8* out_buffer, i32 iterations){
|
||||||
assert(password_hash_size == br_sha256_SIZE);;
|
assert(password_hash_size == br_sha256_SIZE);;
|
||||||
memset(out_buffer, 0, br_sha256_SIZE);
|
memset(out_buffer, 0, br_sha256_SIZE);
|
||||||
br_sha256_context sha256_ctx;
|
br_sha256_context sha256_ctx;
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
#include "cryptography.h"
|
#include "cryptography.h"
|
||||||
#include "tlibc/time.h"
|
#include "tlibc/time.h"
|
||||||
|
|
||||||
void rng_init_sha256_seedFromTime(const br_prng_class* rng_class, const br_prng_class** rng_ctx){
|
void rng_init_sha256_seedFromTime(const br_prng_class** rng_vtable_ptr){
|
||||||
nsec_t time_now = getTimeNsec();
|
nsec_t time_now = getTimeNsec();
|
||||||
rng_class->init(rng_ctx, &br_sha256_vtable, &time_now, sizeof(time_now));
|
const br_prng_class* rng_vtable = *rng_vtable_ptr;
|
||||||
|
rng_vtable->init(rng_vtable_ptr, &br_sha256_vtable, &time_now, sizeof(time_now));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "chat.h"
|
#include "client/client.h"
|
||||||
#include "cryptography/cryptography.h"
|
#include "server/server.h"
|
||||||
|
|
||||||
typedef enum ProgramMode {
|
typedef enum ProgramMode {
|
||||||
Client,
|
Client,
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "tlibc/std.h"
|
#include "tlibc/std.h"
|
||||||
#include "tlibc/string/str.h"
|
#include "tlibc/string/str.h"
|
||||||
|
#include "tlibc/errors.h"
|
||||||
|
|
||||||
#define port_INVALID ((u16)~0)
|
#define port_INVALID ((u16)~0)
|
||||||
#define port_is_invalid(PORT) (PORT == port_INVALID)
|
#define port_is_invalid(PORT) (PORT == port_INVALID)
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "chat.h"
|
#include "server.h"
|
||||||
#include "network/socket.h"
|
|
||||||
#include "db/idb.h"
|
#include "db/idb.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
5
src/server/server.h
Normal file
5
src/server/server.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "network/socket.h"
|
||||||
|
#include "cryptography/cryptography.h"
|
||||||
|
|
||||||
|
Result(void) server_run(cstr server_endpoint_str);
|
||||||
Loading…
Reference in New Issue
Block a user