Saving and loading of key database works

We now can save and load the database from a file and also add hosts.
This commit is contained in:
Johannes Bauer 2019-10-19 21:52:34 +02:00
parent 9c888cbe4e
commit 68c74de050
4 changed files with 90 additions and 13 deletions

View File

@ -28,6 +28,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "editor.h" #include "editor.h"
#include "util.h" #include "util.h"
#include "keydb.h"
#define MAX_COMMAND_ALIAS_COUNT 2 #define MAX_COMMAND_ALIAS_COUNT 2
@ -40,6 +41,7 @@ enum cmd_returncode_t {
struct editor_context_t { struct editor_context_t {
bool running; bool running;
struct keydb_t *keydb;
}; };
struct editor_command_t { struct editor_command_t {
@ -158,7 +160,11 @@ static enum cmd_returncode_t cmd_help(struct editor_context_t *ctx, const char *
} }
static enum cmd_returncode_t cmd_new(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { static enum cmd_returncode_t cmd_new(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) {
return COMMAND_SUCCESS; if (ctx->keydb) {
keydb_free(ctx->keydb);
}
ctx->keydb = keydb_new();
return (ctx->keydb != NULL) ? COMMAND_SUCCESS : COMMAND_FAILURE;
} }
static enum cmd_returncode_t cmd_list(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { static enum cmd_returncode_t cmd_list(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) {
@ -166,7 +172,17 @@ static enum cmd_returncode_t cmd_list(struct editor_context_t *ctx, const char *
} }
static enum cmd_returncode_t cmd_add_host(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { static enum cmd_returncode_t cmd_add_host(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) {
return COMMAND_SUCCESS; if (!ctx->keydb) {
ctx->keydb = keydb_new();
if (!ctx->keydb) {
return COMMAND_FAILURE;
}
}
struct keydb_t *new_keydb = keydb_add_host(ctx->keydb, params[0]);
if (new_keydb) {
ctx->keydb = new_keydb;
}
return new_keydb ? COMMAND_SUCCESS : COMMAND_FAILURE;
} }
static enum cmd_returncode_t cmd_add_volume(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { static enum cmd_returncode_t cmd_add_volume(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) {
@ -182,11 +198,20 @@ static enum cmd_returncode_t cmd_showkey_volume(struct editor_context_t *ctx, co
} }
static enum cmd_returncode_t cmd_open(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { static enum cmd_returncode_t cmd_open(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) {
return COMMAND_SUCCESS; if (ctx->keydb) {
keydb_free(ctx->keydb);
}
ctx->keydb = keydb_read(params[0]);
return (ctx->keydb != NULL) ? COMMAND_SUCCESS : COMMAND_FAILURE;
} }
static enum cmd_returncode_t cmd_save(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { static enum cmd_returncode_t cmd_save(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) {
return COMMAND_SUCCESS; if (!ctx->keydb) {
fprintf(stderr, "No key database loaded.\n");
return COMMAND_FAILURE;
}
bool success = keydb_write(ctx->keydb, params[0], "foobar");
return success ? COMMAND_SUCCESS : COMMAND_FAILURE;
} }
static const struct editor_command_t *find_command(const char *command_name) { static const struct editor_command_t *find_command(const char *command_name) {
@ -275,6 +300,10 @@ void editor_start(void) {
} }
} }
} }
if (editor_context.keydb) {
keydb_free(editor_context.keydb);
}
} }
#ifndef __TEST_EDITOR__ #ifndef __TEST_EDITOR__

View File

@ -423,6 +423,7 @@ bool write_encrypted_file(const char *filename, const void *plaintext, unsigned
if (RAND_bytes(encrypted_file->iv, ENCRYPTED_FILE_IV_SIZE) != 1) { if (RAND_bytes(encrypted_file->iv, ENCRYPTED_FILE_IV_SIZE) != 1) {
log_openssl(LLVL_FATAL, "Failed to get entropy from RAND_bytes for IV"); log_openssl(LLVL_FATAL, "Failed to get entropy from RAND_bytes for IV");
OPENSSL_cleanse(&key, sizeof(key)); OPENSSL_cleanse(&key, sizeof(key));
free(encrypted_file);
return false; return false;
} }
@ -430,6 +431,7 @@ bool write_encrypted_file(const char *filename, const void *plaintext, unsigned
if (!encrypt_aes256_gcm(plaintext, plaintext_length, key.key, encrypted_file->iv, encrypted_file->ciphertext, encrypted_file->auth_tag)) { if (!encrypt_aes256_gcm(plaintext, plaintext_length, key.key, encrypted_file->iv, encrypted_file->ciphertext, encrypted_file->auth_tag)) {
log_libc(LLVL_FATAL, "encryption failed"); log_libc(LLVL_FATAL, "encryption failed");
OPENSSL_cleanse(&key, sizeof(key)); OPENSSL_cleanse(&key, sizeof(key));
free(encrypted_file);
return false; return false;
} }
@ -451,5 +453,6 @@ bool write_encrypted_file(const char *filename, const void *plaintext, unsigned
return false; return false;
} }
free(encrypted_file);
return success; return success;
} }

55
keydb.c
View File

@ -25,18 +25,25 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <openssl/crypto.h>
#include "keydb.h" #include "keydb.h"
#include "util.h" #include "util.h"
#include "log.h"
unsigned int keydb_getsize(const struct keydb_t *keydb) { static unsigned int keydb_getsize_hostcount(unsigned int host_count) {
return sizeof(struct keydb_t) + (keydb->host_count * sizeof(struct host_entry_t)); return sizeof(struct keydb_t) + (host_count * sizeof(struct host_entry_t));
} }
void keydb_init(struct keydb_t *keydb) { static unsigned int keydb_getsize(const struct keydb_t *keydb) {
memset(keydb, 0, sizeof(struct keydb_t)); return keydb_getsize_hostcount(keydb->host_count);
}
struct keydb_t* keydb_new(void) {
struct keydb_t *keydb = calloc(sizeof(struct keydb_t), 1);
keydb->keydb_version = KEYDB_VERSION; keydb->keydb_version = KEYDB_VERSION;
keydb->server_database = true; keydb->server_database = true;
return keydb;
} }
void keydb_free(struct keydb_t *keydb) { void keydb_free(struct keydb_t *keydb) {
@ -44,10 +51,48 @@ void keydb_free(struct keydb_t *keydb) {
free(keydb); free(keydb);
} }
void keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase, enum kdf_t kdf) { struct keydb_t* keydb_add_host(struct keydb_t *keydb, const char *hostname) {
struct keydb_t *new_keydb = realloc(keydb, keydb_getsize_hostcount(keydb->host_count + 1));
if (!new_keydb) {
return NULL;
}
memset(&new_keydb->hosts[new_keydb->host_count], 0, sizeof(struct host_entry_t));
new_keydb->host_count++;
return new_keydb;
}
bool keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase) {
enum kdf_t kdf;
if ((!passphrase) || (strlen(passphrase) == 0)) {
/* For empty password, we can also use garbage KDF */
kdf = KDF_PBKDF2_SHA256_1000;
} else {
kdf = KDF_SCRYPT_N17_r8_p1;
}
return write_encrypted_file(filename, keydb, keydb_getsize(keydb), passphrase, kdf);
} }
struct keydb_t* keydb_read(const char *filename) { struct keydb_t* keydb_read(const char *filename) {
struct decrypted_file_t decrypted_file = read_encrypted_file(filename);
if (!decrypted_file.success) {
return NULL; return NULL;
} }
struct keydb_t *keydb = (struct keydb_t*)decrypted_file.data;
if (keydb->keydb_version != KEYDB_VERSION) {
log_msg(LLVL_ERROR, "keydb in %s could be read, but is of version %u (we expected %u).\n", keydb->keydb_version, KEYDB_VERSION);
OPENSSL_cleanse(decrypted_file.data, decrypted_file.data_length);
free(decrypted_file.data);
return NULL;
}
if (decrypted_file.data_length != keydb_getsize(keydb)) {
log_msg(LLVL_ERROR, "keydb in %s could be read, but was %u bytes long (we expected %u).\n", decrypted_file.data_length, keydb_getsize(keydb));
OPENSSL_cleanse(decrypted_file.data, decrypted_file.data_length);
free(decrypted_file.data);
return NULL;
}
return keydb;
}

View File

@ -55,10 +55,10 @@ struct keydb_t {
}; };
/*************** AUTO GENERATED SECTION FOLLOWS ***************/ /*************** AUTO GENERATED SECTION FOLLOWS ***************/
unsigned int keydb_getsize(const struct keydb_t *keydb); struct keydb_t* keydb_new(void);
void keydb_init(struct keydb_t *keydb);
void keydb_free(struct keydb_t *keydb); void keydb_free(struct keydb_t *keydb);
void keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase, enum kdf_t kdf); struct keydb_t* keydb_add_host(struct keydb_t *keydb, const char *hostname);
bool keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase);
struct keydb_t* keydb_read(const char *filename); struct keydb_t* keydb_read(const char *filename);
/*************** AUTO GENERATED SECTION ENDS ***************/ /*************** AUTO GENERATED SECTION ENDS ***************/