Make shared key store in database

This commit is contained in:
Night Kaly 2024-09-25 03:53:00 +01:00
parent 74952aae1c
commit 2680bc40d6
Signed by: night0721
GPG key ID: 957D67B8DB7A119B
8 changed files with 207 additions and 86 deletions

View file

@ -25,7 +25,7 @@ all: $(SERVER) $(CLIENT)
$(SERVER): $(SERVERSRC) $(LIBSRC)
mkdir -p bin
$(CC) $(SERVERSRC) $(LIBSRC) $(INCLUDE) -o bin/$@ $(CFLAGS) $(LDFLAGS)
$(CC) $(SERVERSRC) $(LIBSRC) $(INCLUDE) -DUSERNAME=\"$(username)\" -o bin/$@ $(CFLAGS) $(LDFLAGS)
$(CLIENT): $(CLIENTSRC) $(LIBSRC)
mkdir -p bin

View file

@ -3,6 +3,9 @@
#include <sqlite3.h>
int sqlite_init();
void get_users();
uint8_t *get_sharedkey(uint8_t *username);
void save_sharedkey(uint8_t *username, uint8_t *shared_key);
void sqlite_init();
#endif

View file

@ -29,5 +29,6 @@ typedef struct keypair_t {
keypair_t *create_keypair(char *username);
keypair_t *get_keypair(char *username);
uint8_t *get_pk_from_ks(char *username);
#endif

View file

@ -10,7 +10,7 @@ void error(int fatal, const char *fmt, ...);
void *memalloc(size_t size);
void *estrdup(void *str);
char *replace_home(char *str);
void mkdir_p(const char *destdir);
void mkdir_p(const char *file);
void write_log(int type, const char *fmt, ...);
void print_bin(const unsigned char *ptr, size_t length);

View file

@ -32,16 +32,25 @@ keypair_t *create_keypair(char *username)
memcpy(pk, pk_data, PK_DATA_SIZE);
memcpy(pk + PK_DATA_SIZE, pk_sign, SIGN_SIZE);
/* USE DB INSTEAD OF FILES */
char pk_path[PATH_MAX], sk_path[PATH_MAX];
sprintf(pk_path, "/home/night/%s_pk", username);
sprintf(sk_path, "/home/night/%s_sk", username);
FILE *pkf = fopen(pk_path, "w+");
FILE *skf = fopen(sk_path, "w+");
fwrite(pk, 1, PK_SIZE, pkf);
fwrite(sk, 1, SK_SIZE, skf);
fclose(pkf);
fclose(skf);
char keyf_path[PATH_MAX];
char *data_dir = replace_home(CLIENT_DATA_DIR);
snprintf(keyf_path, PATH_MAX, "%s/%s/keys", data_dir, USERNAME);
free(data_dir);
if (access(keyf_path, W_OK) != 0) {
/* If data file doesn't exist, most likely data dir won't exist too */
mkdir_p(keyf_path);
}
FILE *keyf = fopen(keyf_path, "w+");
if (!keyf) {
error(1, "Error opening key file to write");
return NULL;
}
/* Write key to file */
fwrite(pk, 1, PK_SIZE, keyf);
fwrite(sk, 1, SK_SIZE, keyf);
fclose(keyf);
keypair_t *kp = memalloc(sizeof(keypair_t));
memcpy(kp->pk.raw, pk_raw, PK_RAW_SIZE);
@ -51,29 +60,35 @@ keypair_t *create_keypair(char *username)
memcpy(kp->pk.full, pk, PK_SIZE);
memcpy(kp->sk, sk, SK_SIZE);
write_log(LOG_INFO, "Created key pair");
return kp;
}
keypair_t *get_keypair(char *username)
{
/* REPLACE WITH DB */
char pk_path[PATH_MAX], sk_path[PATH_MAX];
sprintf(pk_path, "/home/night/%s_pk", username);
sprintf(sk_path, "/home/night/%s_sk", username);
FILE *pkf = fopen(pk_path, "r");
FILE *skf = fopen(sk_path, "r");
if (!pkf || !skf) {
char keyf_path[PATH_MAX];
char *data_dir = replace_home(CLIENT_DATA_DIR);
snprintf(keyf_path, PATH_MAX, "%s/%s/keys", data_dir, USERNAME);
free(data_dir);
if (access(keyf_path, W_OK) != 0) {
/* If data file doesn't exist, most likely data dir won't exist too */
mkdir_p(keyf_path);
/* Create key pair as file doesn't exist */
create_keypair(username);
printf("Error opening key files.\n");
}
FILE *keyf = fopen(keyf_path, "r");
if (!keyf) {
error(1, "Error opening key file to read");
return NULL;
}
uint8_t pk[PK_SIZE], sk[SK_SIZE];
fread(pk, 1, PK_SIZE, pkf);
fread(sk, 1, SK_SIZE, skf);
fclose(pkf);
fclose(skf);
fread(pk, 1, PK_SIZE, keyf);
fread(sk, 1, SK_SIZE, keyf);
fclose(keyf);
keypair_t *kp = memalloc(sizeof(keypair_t));
@ -87,3 +102,21 @@ keypair_t *get_keypair(char *username)
return kp;
}
/*
* Get public key from key server
*/
uint8_t *get_pk_from_ks(char *username)
{
size_t bin_len = PK_RAW_SIZE;
unsigned char *bin = memalloc(bin_len);
/* TEMPORARY */
if (strcmp(username, "night") == 0) {
sodium_hex2bin(bin, bin_len, "e2f0287d9c23aed8404dd8ba407e7dff8abe40fa98f0b9adf74904978a5fcd50", PK_RAW_SIZE * 2, NULL, NULL, NULL);
return bin;
} else if (strcmp(username, "palanix") == 0) {
sodium_hex2bin(bin, bin_len, "932aee08aa338108e49f65a5c4f0eb0a08a15bf717fdf8c0ff60eefd0ea014ae", PK_RAW_SIZE * 2, NULL, NULL, NULL);
return bin;
}
return NULL;
}

View file

@ -204,14 +204,14 @@ int verify_packet(packet_t *pkt, int fd)
memcpy(from, pkt->data, MAX_NAME);
/* TODO: replace with db operations */
keypair_t *kp_from = get_keypair(from);
uint8_t *pk = get_pk_from_ks(from);
/* Verify data confidentiality by signature */
/* Verify data integrity by hash */
uint8_t hash[HASH_SIZE];
crypto_generichash(hash, HASH_SIZE, pkt->data, pkt->length, NULL, 0);
if (crypto_sign_verify_detached(pkt->signature, hash, HASH_SIZE, kp_from->pk.raw) != 0) {
if (crypto_sign_verify_detached(pkt->signature, hash, HASH_SIZE, pk) != 0) {
/* Not match */
error(0, "Cannot verify data integrity");
packet_t *error_pkt = create_packet(ZSM_STA_ERROR_INTEGRITY,

View file

@ -76,28 +76,38 @@ char *replace_home(char *str)
/*
* Recursively create directory by creating each subdirectory
* like mkdir -p
* Create the parent folder(s) of given file
*/
void mkdir_p(const char *destdir)
void mkdir_p(const char *file)
{
char *path = memalloc(PATH_MAX);
char dir_path[PATH_MAX];
dir_path[0] = '\0';
if (destdir[0] == '~') {
if (file[0] == '~') {
char *home = getenv("HOME");
if (home == NULL) {
write_log(LOG_ERROR, "$HOME not defined");
return;
}
/* replace ~ with home */
snprintf(path, PATH_MAX, "%s%s", home, destdir + 1);
snprintf(path, PATH_MAX, "%s%s", home, file + 1);
} else {
strcpy(path, destdir);
strcpy(path, file);
}
/* fix first / not appearing in the string */
if (path[0] == '/')
strcat(dir_path, "/");
/* Find last occurrence of '/' */
char *last_slash = strrchr(path, '/');
/* Remove last slash */
if (last_slash != NULL) {
path[last_slash - path] = '\0';
}
char *token = strtok(path, "/");
while (token != NULL) {
strcat(dir_path, token);
@ -127,13 +137,13 @@ void write_log(int type, const char *fmt, ...)
va_list args;
va_start(args, fmt);
char *client_log = memalloc(PATH_MAX);
char client_log[PATH_MAX];
char *data_dir = replace_home(CLIENT_DATA_DIR);
snprintf(client_log, PATH_MAX, "%s/%s", data_dir, "zen.log");
snprintf(client_log, PATH_MAX, "%s/%s/zen.log", data_dir, USERNAME);
free(data_dir);
if (access(client_log, W_OK) != 0) {
/* If log file doesn't exist, most likely data dir won't exist too */
mkdir_p(CLIENT_DATA_DIR);
mkdir_p(client_log);
}
FILE *log = fopen(client_log, "a");
@ -148,8 +158,9 @@ void write_log(int type, const char *fmt, ...)
strftime(time, 22, "%Y-%m-%d %H:%M:%S ", t);
char details[2 + type_len + 22];
snprintf(details, 2 + type_len + 22, "%s%s", logtype, time);
fprintf(log, "%s\n", details);
fprintf(log, "%s", details);
vfprintf(log, fmt, args);
fprintf(log, "\n");
fclose(log);
}
va_end(args);

View file

@ -5,68 +5,141 @@
#include "client/db.h"
#include "client/user.h"
static int callback(void *ignore, int argc, char **argv, char **azColName)
sqlite3 *db;
char zen_db_path[PATH_MAX];
static int get_users_callback(void *_, int argc, char **argv, char **col_name)
{
/*
for(int i = 0; i < argc; i++) {
printf("%s = %s\n", column[i], argv[i] ? argv[i] : "NULL");
}
*/
add_username(argv[0]);
return 0;
}
static int get_shared_key(void *ignore, int argc, char **argv, char **column)
void get_users()
{
for(int i = 0; i < argc; i++) {
printf("%s = %s\n", column[i], argv[i] ? argv[i] : "NULL");
char *err_msg;
sqlite3_stmt *statement;
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
error(0, "Cannot open database: %s", sqlite3_errmsg(db));
sqlite3_close(db);
}
printf("\n");
return 0;
char *sql = "SELECT * FROM Keys;";
if (sqlite3_exec(db, sql, get_users_callback, NULL, &err_msg)
!= SQLITE_OK) {
error(0, "Failed to exec statement: %s", err_msg);
sqlite3_close(db);
}
sqlite3_close(db);
return;
}
/*
* Get shared key betweeen username
*/
uint8_t *get_sharedkey(uint8_t *username)
{
sqlite3_stmt *statement;
uint8_t *shared_key = memalloc(SHARED_KEY_SIZE);
/* Make all bytes be 0 */
memset(shared_key, 0, SHARED_KEY_SIZE);
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
error(0, "Cannot open database: %s", sqlite3_errmsg(db));
sqlite3_close(db);
}
char *sql = "SELECT SharedKey FROM Keys WHERE Username = ?;";
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) != SQLITE_OK) {
error(0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
sqlite3_close(db);
}
sqlite3_bind_text(statement, 1, username, strlen(username), SQLITE_STATIC);
if (sqlite3_step(statement) == SQLITE_ROW) {
const void *blob = sqlite3_column_blob(statement, 0);
memcpy(shared_key, blob, SHARED_KEY_SIZE);
} else {
free(shared_key);
/* Set it to NULL so it can be returned */
shared_key = NULL;
}
sqlite3_finalize(statement);
sqlite3_close(db);
return shared_key;
}
int sqlite_init()
/*
* Saved shared key with username to database
*/
void save_sharedkey(uint8_t *username, uint8_t *shared_key)
{
sqlite3 *db;
char *err_msg = 0;
char *zen_db = memalloc(PATH_MAX);
char *data_dir = replace_home(CLIENT_DATA_DIR);
snprintf(zen_db, PATH_MAX, "%s/%s", data_dir, "data.db");
free(data_dir);
if (access(zen_db, W_OK) != 0) {
/* If data file doesn't exist, most likely data dir won't exist too */
mkdir_p(CLIENT_DATA_DIR);
}
int rc = sqlite3_open(zen_db, &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
error(0, "Cannot open database: %s", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
char *users_statement = "CREATE TABLE IF NOT EXISTS Users(Username TEXT, SharedKey TEXT, Test TEXT);";
char *shared_key_statement = "SELECT * FROM Users;";
char *messages_statement = "CREATE TABLE IF NOT EXISTS Messages(Username TEXT, );";
//"INSERT INTO Users VALUES('night', 'test', '1');";
sqlite3_stmt *statement;
rc = sqlite3_exec(db, users_statement, 0, 0, &err_msg);
/* Statement to execute with values to be replaced */
char *sql = "INSERT OR REPLACE INTO Keys (Username,SharedKey)"
"VALUES (?,?);";
printf("in db\n");
print_bin(shared_key, SHARED_KEY_SIZE);
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) != SQLITE_OK) {
error(0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
sqlite3_close(db);
}
sqlite3_bind_text(statement, 1, username, strlen(username), SQLITE_STATIC);
sqlite3_bind_blob(statement, 2, shared_key, SHARED_KEY_SIZE, SQLITE_STATIC);
if (rc != SQLITE_OK) {
error(0, "SQL error: %s", err_msg);
if (sqlite3_step(statement) != SQLITE_DONE) {
error(0, "Failed to execute statement");
sqlite3_close(db);
}
sqlite3_finalize(statement);
sqlite3_close(db);
write_log(LOG_INFO, "Saved shared key with %s to database", username);
}
void sqlite_init()
{
char *err_msg;
char *data_dir = replace_home(CLIENT_DATA_DIR);
snprintf(zen_db_path, PATH_MAX, "%s/%s/data.db", data_dir, USERNAME);
free(data_dir);
if (access(zen_db_path, W_OK) != 0) {
/* If data file doesn't exist, most likely data dir won't exist too */
mkdir_p(zen_db_path);
}
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
deinit();
error(1, "Cannot open database: %s", sqlite3_errmsg(db));
sqlite3_close(db);
}
/* Create Keys Table if it is doesn't exist with Username being id */
char *create_keys_table = "CREATE TABLE IF NOT EXISTS Keys("
"Username TEXT NOT NULL, SharedKey BLOB NOT NULL,"
"PRIMARY KEY(Username));";
if (sqlite3_exec(db, create_keys_table, 0, 0, &err_msg) != SQLITE_OK) {
error(0, "Cannot create Keys table: %s", err_msg);
sqlite3_free(err_msg);
} else {
/* error(0, "Table created successfully"); */
}
// Select and print all entries
rc = sqlite3_exec(db, "SELECT * FROM Users", callback, NULL, &err_msg);
if (rc != SQLITE_OK) {
error(0, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
write_log(LOG_INFO, "Keys Table created successfully");
}
sqlite3_close(db);
return 0;
}