Make shared key store in database
This commit is contained in:
parent
74952aae1c
commit
2680bc40d6
8 changed files with 207 additions and 86 deletions
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -76,29 +76,39 @@ 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, "/");
|
||||
|
||||
char *token = strtok(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);
|
||||
strcat(dir_path, "/");
|
||||
|
@ -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);
|
||||
|
|
165
src/zen/db.c
165
src/zen/db.c
|
@ -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");
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
char *err_msg;
|
||||
sqlite3_stmt *statement;
|
||||
|
||||
|
||||
int sqlite_init()
|
||||
{
|
||||
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);
|
||||
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
|
||||
error(0, "Cannot open database: %s", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
int rc = sqlite3_open(zen_db, &db);
|
||||
char *sql = "SELECT * FROM Keys;";
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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_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);
|
||||
|
||||
rc = sqlite3_exec(db, users_statement, 0, 0, &err_msg);
|
||||
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
|
||||
error(0, "Cannot open database: %s", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
error(0, "SQL error: %s", err_msg);
|
||||
sqlite3_free(err_msg);
|
||||
} else {
|
||||
/* error(0, "Table created successfully"); */
|
||||
}
|
||||
char *sql = "SELECT SharedKey FROM Keys WHERE Username = ?;";
|
||||
|
||||
// Select and print all entries
|
||||
rc = sqlite3_exec(db, "SELECT * FROM Users", callback, NULL, &err_msg);
|
||||
if (sqlite3_prepare_v2(db, sql, -1, &statement, NULL) != SQLITE_OK) {
|
||||
error(0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
error(0, "SQL error: %s\n", err_msg);
|
||||
sqlite3_free(err_msg);
|
||||
}
|
||||
sqlite3_bind_text(statement, 1, username, strlen(username), SQLITE_STATIC);
|
||||
|
||||
sqlite3_close(db);
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
sqlite3_finalize(statement);
|
||||
sqlite3_close(db);
|
||||
return shared_key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Saved shared key with username to database
|
||||
*/
|
||||
void save_sharedkey(uint8_t *username, uint8_t *shared_key)
|
||||
{
|
||||
if (sqlite3_open(zen_db_path, &db) != SQLITE_OK) {
|
||||
error(0, "Cannot open database: %s", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
sqlite3_stmt *statement;
|
||||
|
||||
/* 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 (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 {
|
||||
write_log(LOG_INFO, "Keys Table created successfully");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue