From b0909557ade0be0d7dae6256b93a9a3b759a4cce Mon Sep 17 00:00:00 2001 From: Johannes Bauer Date: Sat, 26 Jun 2021 23:27:57 +0200 Subject: [PATCH] Refactoring of version code We want to introduce a new feature (volumes with discard support) which will cause file incompatibility. This means we need to prepare data migration code. This prepares that change. --- Makefile | 2 +- client.c | 10 +++--- editor.c | 42 ++++++++++++------------- keydb.c | 84 ++++++++++++++++++++++++------------------------- keydb.h | 64 ++++++++++++++++++++++--------------- server.c | 10 +++--- vaulted_keydb.c | 12 +++---- vaulted_keydb.h | 8 ++--- 8 files changed, 123 insertions(+), 109 deletions(-) diff --git a/Makefile b/Makefile index 712b3d7..94924fd 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ INSTALL_PREFIX := /usr/local/ CFLAGS := -Wall -Wextra -Wshadow -Wswitch -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Werror=implicit-function-declaration -Werror=format -Wno-unused-parameter CFLAGS += -O3 -std=c11 -pthread -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=500 -DBUILD_REVISION='"$(BUILD_REVISION)"' CFLAGS += `pkg-config --cflags openssl` -CFLAGS += -ggdb3 -DDEBUG -fsanitize=address -fsanitize=undefined -fsanitize=leak +#CFLAGS += -ggdb3 -DDEBUG -fsanitize=address -fsanitize=undefined -fsanitize=leak PYPGMOPTS := ../Python/pypgmopts/pypgmopts LDFLAGS := `pkg-config --libs openssl` diff --git a/client.c b/client.c index 1c10d6c..ddfac7d 100644 --- a/client.c +++ b/client.c @@ -47,7 +47,7 @@ struct keyclient_t { const struct pgmopts_client_t *opts; - struct keydb_t *keydb; + keydb_t *keydb; bool volume_unlocked[MAX_VOLUMES_PER_HOST]; unsigned char identifier[ASCII_UUID_BUFSIZE]; double broadcast_start_time; @@ -61,7 +61,7 @@ static int psk_client_callback(SSL *ssl, const EVP_MD *md, const unsigned char * return openssl_tls13_psk_establish_session(ssl, key_client->keydb->hosts[0].tls_psk, PSK_SIZE_BYTES, EVP_sha256(), sessptr); } -static bool unlock_luks_volume(const struct volume_entry_t *volume, const struct msg_t *unlock_msg) { +static bool unlock_luks_volume(const volume_entry_t *volume, const struct msg_t *unlock_msg) { bool success = true; char luks_passphrase[LUKS_PASSPHRASE_TEXT_SIZE_BYTES]; if (ascii_encode(luks_passphrase, sizeof(luks_passphrase), unlock_msg->luks_passphrase_raw, sizeof(unlock_msg->luks_passphrase_raw))) { @@ -75,8 +75,8 @@ static bool unlock_luks_volume(const struct volume_entry_t *volume, const struct } static bool attempt_unlock_luks_volume(struct keyclient_t *keyclient, const struct msg_t *unlock_msg) { - const struct host_entry_t *host = &keyclient->keydb->hosts[0]; - const struct volume_entry_t* volume = keydb_get_volume_by_uuid(host, unlock_msg->volume_uuid); + const host_entry_t *host = &keyclient->keydb->hosts[0]; + const volume_entry_t* volume = keydb_get_volume_by_uuid(host, unlock_msg->volume_uuid); char volume_uuid_str[ASCII_UUID_BUFSIZE]; sprintf_uuid(volume_uuid_str, unlock_msg->volume_uuid); if (!volume) { @@ -307,7 +307,7 @@ bool keyclient_start(const struct pgmopts_client_t *opts) { break; } - struct host_entry_t *host = &keyclient.keydb->hosts[0]; + host_entry_t *host = &keyclient.keydb->hosts[0]; if (host->volume_count == 0) { log_msg(LLVL_FATAL, "No volumes found in exported database %s.", opts->filename); success = false; diff --git a/editor.c b/editor.c index dfda178..2aa8b4b 100644 --- a/editor.c +++ b/editor.c @@ -45,7 +45,7 @@ enum cmd_returncode_t { struct editor_context_t { bool running; - struct keydb_t *keydb; + keydb_t *keydb; char filename[MAX_FILENAME_LENGTH]; char passphrase[MAX_PASSPHRASE_LENGTH]; }; @@ -227,14 +227,14 @@ static enum cmd_returncode_t cmd_list(struct editor_context_t *ctx, const char * printf("No key database loaded.\n"); return COMMAND_FAILURE; } - printf("Keydb version %d, %s database, %d hosts.\n", ctx->keydb->keydb_version, ctx->keydb->server_database ? "server" : "client", ctx->keydb->host_count); + printf("Keydb version %d, %s database, %d hosts.\n", ctx->keydb->common.keydb_version, ctx->keydb->server_database ? "server" : "client", ctx->keydb->host_count); for (unsigned int i = 0; i < ctx->keydb->host_count; i++) { - const struct host_entry_t *host = &ctx->keydb->hosts[i]; + const host_entry_t *host = &ctx->keydb->hosts[i]; char uuid[48]; sprintf_uuid(uuid, host->host_uuid); printf(" Host %d: \"%s\" UUID %s -- %d volumes:\n", i + 1, host->host_name, uuid, host->volume_count); for (unsigned int j = 0; j < host->volume_count; j++) { - const struct volume_entry_t *volume = &host->volumes[j]; + const volume_entry_t *volume = &host->volumes[j]; sprintf_uuid(uuid, volume->volume_uuid); printf(" Volume %d: \"%s\" UUID %s\n", j + 1, volume->devmapper_name, uuid); } @@ -265,12 +265,12 @@ static enum cmd_returncode_t cmd_del_host(struct editor_context_t *ctx, const ch return success ? COMMAND_SUCCESS : COMMAND_FAILURE; } -static struct host_entry_t* cmd_gethost(struct editor_context_t *ctx, const char *host_name) { +static host_entry_t* cmd_gethost(struct editor_context_t *ctx, const char *host_name) { if (!ctx->keydb) { fprintf(stderr, "No key database loaded.\n"); return NULL; } - struct host_entry_t *host = keydb_get_host_by_name(ctx->keydb, host_name); + host_entry_t *host = keydb_get_host_by_name(ctx->keydb, host_name); if (!host) { fprintf(stderr, "No such host: %s\n", host_name); return NULL; @@ -278,13 +278,13 @@ static struct host_entry_t* cmd_gethost(struct editor_context_t *ctx, const char return host; } -static struct volume_entry_t* cmd_getvolume(struct editor_context_t *ctx, const char *host_name, const char *devmapper_name) { - struct host_entry_t *host = cmd_gethost(ctx, host_name); +static volume_entry_t* cmd_getvolume(struct editor_context_t *ctx, const char *host_name, const char *devmapper_name) { + host_entry_t *host = cmd_gethost(ctx, host_name); if (!host) { return NULL; } - struct volume_entry_t *volume = keydb_get_volume_by_name(host, devmapper_name); + volume_entry_t *volume = keydb_get_volume_by_name(host, devmapper_name); if (!volume) { fprintf(stderr, "No such volume \"%s\" for host \"%s\"\n", devmapper_name, host_name); return NULL; @@ -294,11 +294,11 @@ static struct volume_entry_t* cmd_getvolume(struct editor_context_t *ctx, const static enum cmd_returncode_t cmd_rekey_host(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { const char *host_name = params[0]; - struct host_entry_t *host = cmd_gethost(ctx, host_name); + host_entry_t *host = cmd_gethost(ctx, host_name); return host && keydb_rekey_host(host) ? COMMAND_SUCCESS : COMMAND_FAILURE; } -static enum cmd_returncode_t cmd_do_showkey_volume(struct volume_entry_t *volume) { +static enum cmd_returncode_t cmd_do_showkey_volume(volume_entry_t *volume) { char luks_passphrase[LUKS_PASSPHRASE_TEXT_SIZE_BYTES]; if (!keydb_get_volume_luks_passphrase(volume, luks_passphrase, sizeof(luks_passphrase))) { OPENSSL_cleanse(luks_passphrase, sizeof(luks_passphrase)); @@ -315,7 +315,7 @@ static enum cmd_returncode_t cmd_do_showkey_volume(struct volume_entry_t *volume static enum cmd_returncode_t cmd_add_volume(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { const char *host_name = params[0]; - struct host_entry_t *host = cmd_gethost(ctx, host_name); + host_entry_t *host = cmd_gethost(ctx, host_name); if (!host) { return COMMAND_FAILURE; } @@ -328,7 +328,7 @@ static enum cmd_returncode_t cmd_add_volume(struct editor_context_t *ctx, const } uint8_t volume_uuid[16]; parse_uuid(volume_uuid, volume_uuid_str); - struct volume_entry_t *volume = keydb_add_volume(host, devmapper_name, volume_uuid); + volume_entry_t *volume = keydb_add_volume(host, devmapper_name, volume_uuid); if (volume) { return cmd_do_showkey_volume(volume); } else { @@ -340,7 +340,7 @@ static enum cmd_returncode_t cmd_del_volume(struct editor_context_t *ctx, const const char *host_name = params[0]; const char *devmapper_name = params[1]; - struct host_entry_t *host = cmd_gethost(ctx, host_name); + host_entry_t *host = cmd_gethost(ctx, host_name); if (!host) { return COMMAND_FAILURE; } @@ -354,7 +354,7 @@ static enum cmd_returncode_t cmd_rekey_volume(struct editor_context_t *ctx, cons const char *host_name = params[0]; const char *devmapper_name = params[1]; - struct volume_entry_t *volume = cmd_getvolume(ctx, host_name, devmapper_name); + volume_entry_t *volume = cmd_getvolume(ctx, host_name, devmapper_name); if (!volume) { return COMMAND_FAILURE; } @@ -368,7 +368,7 @@ static enum cmd_returncode_t cmd_showkey_volume(struct editor_context_t *ctx, co const char *host_name = params[0]; const char *devmapper_name = params[1]; - struct volume_entry_t *volume = cmd_getvolume(ctx, host_name, devmapper_name); + volume_entry_t *volume = cmd_getvolume(ctx, host_name, devmapper_name); if (!volume) { return COMMAND_FAILURE; } @@ -417,12 +417,12 @@ static enum cmd_returncode_t cmd_save(struct editor_context_t *ctx, const char * static enum cmd_returncode_t cmd_export(struct editor_context_t *ctx, const char *cmdname, unsigned int param_cnt, char **params) { const char *host_name = params[0]; const char *filename = params[1]; - struct host_entry_t *host = cmd_gethost(ctx, host_name); + host_entry_t *host = cmd_gethost(ctx, host_name); if (!host) { return COMMAND_FAILURE; } - struct keydb_t *pubdb = keydb_export_public(host); + keydb_t *pubdb = keydb_export_public(host); char passphrase[MAX_PASSPHRASE_LENGTH]; if (!query_passphrase("Client passphrase: ", passphrase, sizeof(passphrase))) { fprintf(stderr, "Failed to read export passphrase.\n"); @@ -473,7 +473,7 @@ static enum cmd_returncode_t cmd_rawdump(struct editor_context_t *ctx, const cha } fprintf(stderr, "Version %d, %s, %d hosts.\n", ctx->keydb->keydb_version, ctx->keydb->server_database ? "server" : "client", ctx->keydb->host_count); for (unsigned int i = 0; i < ctx->keydb->host_count; i++) { - struct host_entry_t *host = &ctx->keydb->hosts[i]; + host_entry_t *host = &ctx->keydb->hosts[i]; fprintf(stderr, "Host %d:\n", i); { char host_uuid[ASCII_UUID_BUFSIZE]; @@ -488,8 +488,8 @@ static enum cmd_returncode_t cmd_rawdump(struct editor_context_t *ctx, const cha dump_hexline(stderr, " tls_psk ", host->tls_psk, sizeof(host->tls_psk), false); fprintf(stderr, " volume_count %u\n", host->volume_count); for (unsigned int j = 0; j < MAX_VOLUMES_PER_HOST; j++) { - struct volume_entry_t *volume = &host->volumes[j]; - if (!is_zero(volume, sizeof(struct volume_entry_t))) { + volume_entry_t *volume = &host->volumes[j]; + if (!is_zero(volume, sizeof(volume_entry_t))) { fprintf(stderr, " Host %d / Volume %d:\n", i, j); dump_hexline(stderr, " volume_uuid ", volume->volume_uuid, sizeof(volume->volume_uuid), false); dump_hexline(stderr, " devmapper_name ", volume->devmapper_name, sizeof(volume->devmapper_name), true); diff --git a/keydb.c b/keydb.c index 32c7839..46fe1b2 100644 --- a/keydb.c +++ b/keydb.c @@ -34,22 +34,22 @@ #include "log.h" static unsigned int keydb_getsize_hostcount(unsigned int host_count) { - return sizeof(struct keydb_t) + (host_count * sizeof(struct host_entry_t)); + return sizeof(keydb_t) + (host_count * sizeof(host_entry_t)); } -static unsigned int keydb_getsize(const struct keydb_t *keydb) { +static unsigned int keydb_getsize(const keydb_t *keydb) { 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_t* keydb_new(void) { + keydb_t *keydb = calloc(sizeof(keydb_t), 1); + keydb->common.keydb_version = KEYDB_CURRENT_VERSION; keydb->server_database = true; return keydb; } -struct keydb_t* keydb_export_public(struct host_entry_t *host) { - struct keydb_t *public_db = keydb_new(); +keydb_t* keydb_export_public(host_entry_t *host) { + keydb_t *public_db = keydb_new(); if (!public_db) { return NULL; } @@ -61,28 +61,28 @@ struct keydb_t* keydb_export_public(struct host_entry_t *host) { } /* Copy over whole entry */ - struct host_entry_t *public_host = &public_db->hosts[0]; + host_entry_t *public_host = &public_db->hosts[0]; *public_host = *host; /* But remove all LUKS passphrases of course, this is for the luksrku client */ for (unsigned int i = 0; i < host->volume_count; i++) { - struct volume_entry_t *volume = &public_host->volumes[i]; + volume_entry_t *volume = &public_host->volumes[i]; memset(volume->luks_passphrase_raw, 0, sizeof(volume->luks_passphrase_raw)); } return public_db; } -void keydb_free(struct keydb_t *keydb) { +void keydb_free(keydb_t *keydb) { if (keydb) { OPENSSL_cleanse(keydb, keydb_getsize(keydb)); free(keydb); } } -struct volume_entry_t* keydb_get_volume_by_name(struct host_entry_t *host, const char *devmapper_name) { +volume_entry_t* keydb_get_volume_by_name(host_entry_t *host, const char *devmapper_name) { for (unsigned int i = 0; i < host->volume_count; i++) { - struct volume_entry_t *volume = &host->volumes[i]; + volume_entry_t *volume = &host->volumes[i]; if (!strncasecmp(volume->devmapper_name, devmapper_name, sizeof(volume->devmapper_name) - 1)) { return volume; } @@ -90,9 +90,9 @@ struct volume_entry_t* keydb_get_volume_by_name(struct host_entry_t *host, const return NULL; } -struct host_entry_t* keydb_get_host_by_name(struct keydb_t *keydb, const char *host_name) { +host_entry_t* keydb_get_host_by_name(keydb_t *keydb, const char *host_name) { for (unsigned int i = 0; i < keydb->host_count; i++) { - struct host_entry_t *host = &keydb->hosts[i]; + host_entry_t *host = &keydb->hosts[i]; if (!strncasecmp(host->host_name, host_name, sizeof(host->host_name) - 1)) { return host; } @@ -100,9 +100,9 @@ struct host_entry_t* keydb_get_host_by_name(struct keydb_t *keydb, const char *h return NULL; } -const struct volume_entry_t* keydb_get_volume_by_uuid(const struct host_entry_t *host, const uint8_t uuid[static 16]) { +const volume_entry_t* keydb_get_volume_by_uuid(const host_entry_t *host, const uint8_t uuid[static 16]) { for (unsigned int i = 0; i < host->volume_count; i++) { - const struct volume_entry_t *volume = &host->volumes[i]; + const volume_entry_t *volume = &host->volumes[i]; if (!memcmp(volume->volume_uuid, uuid, 16)) { return volume; } @@ -110,7 +110,7 @@ const struct volume_entry_t* keydb_get_volume_by_uuid(const struct host_entry_t return NULL; } -int keydb_get_host_index(const struct keydb_t *keydb, const struct host_entry_t *host) { +int keydb_get_host_index(const keydb_t *keydb, const host_entry_t *host) { int index = host - keydb->hosts; if (index < 0) { return -1; @@ -120,7 +120,7 @@ int keydb_get_host_index(const struct keydb_t *keydb, const struct host_entry_t return index; } -int keydb_get_volume_index(const struct host_entry_t *host, const struct volume_entry_t *volume) { +int keydb_get_volume_index(const host_entry_t *host, const volume_entry_t *volume) { int index = volume - host->volumes; if (index < 0) { return -1; @@ -130,9 +130,9 @@ int keydb_get_volume_index(const struct host_entry_t *host, const struct volume_ return index; } -const struct host_entry_t* keydb_get_host_by_uuid(const struct keydb_t *keydb, const uint8_t uuid[static 16]) { +const host_entry_t* keydb_get_host_by_uuid(const keydb_t *keydb, const uint8_t uuid[static 16]) { for (unsigned int i = 0; i < keydb->host_count; i++) { - const struct host_entry_t *host = &keydb->hosts[i]; + const host_entry_t *host = &keydb->hosts[i]; if (!memcmp(host->host_uuid, uuid, 16)) { return host; } @@ -140,26 +140,26 @@ const struct host_entry_t* keydb_get_host_by_uuid(const struct keydb_t *keydb, c return NULL; } -bool keydb_add_host(struct keydb_t **keydb, const char *host_name) { +bool keydb_add_host(keydb_t **keydb, const char *host_name) { if (strlen(host_name) > MAX_HOST_NAME_LENGTH - 1) { log_msg(LLVL_ERROR, "Host name \"%s\" exceeds maximum length of %d characters.", host_name, MAX_HOST_NAME_LENGTH - 1); return false; } - struct keydb_t *old_keydb = *keydb; + keydb_t *old_keydb = *keydb; if (keydb_get_host_by_name(old_keydb, host_name)) { log_msg(LLVL_ERROR, "Host name \"%s\" already present in key database.", host_name); return false; } - struct keydb_t *new_keydb = realloc(old_keydb, keydb_getsize_hostcount(old_keydb->host_count + 1)); + keydb_t *new_keydb = realloc(old_keydb, keydb_getsize_hostcount(old_keydb->host_count + 1)); if (!new_keydb) { return false; } *keydb = new_keydb; - struct host_entry_t *host = &new_keydb->hosts[new_keydb->host_count]; - memset(host, 0, sizeof(struct host_entry_t)); + host_entry_t *host = &new_keydb->hosts[new_keydb->host_count]; + memset(host, 0, sizeof(host_entry_t)); if (!uuid_randomize(host->host_uuid)) { /* We keep the reallocation but do not increase the host count */ return false; @@ -174,9 +174,9 @@ bool keydb_add_host(struct keydb_t **keydb, const char *host_name) { return true; } -bool keydb_del_host_by_name(struct keydb_t **keydb, const char *host_name) { - struct keydb_t *old_keydb = *keydb; - struct host_entry_t *host = keydb_get_host_by_name(old_keydb, host_name); +bool keydb_del_host_by_name(keydb_t **keydb, const char *host_name) { + keydb_t *old_keydb = *keydb; + host_entry_t *host = keydb_get_host_by_name(old_keydb, host_name); if (!host) { log_msg(LLVL_ERROR, "No such host: \"%s\"", host_name); return false; @@ -189,16 +189,16 @@ bool keydb_del_host_by_name(struct keydb_t **keydb, const char *host_name) { } /* We keep the memory for now and do not realloc */ - array_remove(old_keydb->hosts, sizeof(struct host_entry_t), old_keydb->host_count, host_index); + array_remove(old_keydb->hosts, sizeof(host_entry_t), old_keydb->host_count, host_index); old_keydb->host_count--; return true; } -bool keydb_rekey_host(struct host_entry_t *host) { +bool keydb_rekey_host(host_entry_t *host) { return buffer_randomize(host->tls_psk, sizeof(host->tls_psk)); } -struct volume_entry_t* keydb_add_volume(struct host_entry_t *host, const char *devmapper_name, const uint8_t volume_uuid[static 16]) { +volume_entry_t* keydb_add_volume(host_entry_t *host, const char *devmapper_name, const uint8_t volume_uuid[static 16]) { if (strlen(devmapper_name) > MAX_DEVMAPPER_NAME_LENGTH - 1) { log_msg(LLVL_ERROR, "Device mapper name \"%s\" exceeds maximum length of %d characters.", devmapper_name, MAX_DEVMAPPER_NAME_LENGTH - 1); return false; @@ -213,7 +213,7 @@ struct volume_entry_t* keydb_add_volume(struct host_entry_t *host, const char *d return NULL; } - struct volume_entry_t *volume = &host->volumes[host->volume_count]; + volume_entry_t *volume = &host->volumes[host->volume_count]; memcpy(volume->volume_uuid, volume_uuid, 16); strncpy(volume->devmapper_name, devmapper_name, sizeof(volume->devmapper_name) - 1); if (!buffer_randomize(volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw))) { @@ -224,8 +224,8 @@ struct volume_entry_t* keydb_add_volume(struct host_entry_t *host, const char *d return volume; } -bool keydb_del_volume(struct host_entry_t *host, const char *devmapper_name) { - struct volume_entry_t *volume = keydb_get_volume_by_name(host, devmapper_name); +bool keydb_del_volume(host_entry_t *host, const char *devmapper_name) { + volume_entry_t *volume = keydb_get_volume_by_name(host, devmapper_name); if (!volume) { log_msg(LLVL_ERROR, "No such volume \"%s\" for host \"%s\".", devmapper_name, host->host_name); return false; @@ -235,7 +235,7 @@ bool keydb_del_volume(struct host_entry_t *host, const char *devmapper_name) { log_msg(LLVL_FATAL, "Fatal error determining volume index of \"%s\" for host \"%s\".", devmapper_name, host->host_name); return false; } - if (!array_remove(host->volumes, sizeof(struct volume_entry_t), host->volume_count, index)) { + if (!array_remove(host->volumes, sizeof(volume_entry_t), host->volume_count, index)) { log_msg(LLVL_ERROR, "Failed to remove \"%s\" of host \"%s\".", devmapper_name, host->host_name); return false; } @@ -243,15 +243,15 @@ bool keydb_del_volume(struct host_entry_t *host, const char *devmapper_name) { return true; } -bool keydb_rekey_volume(struct volume_entry_t *volume) { +bool keydb_rekey_volume(volume_entry_t *volume) { return buffer_randomize(volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw)); } -bool keydb_get_volume_luks_passphrase(const struct volume_entry_t *volume, char *dest, unsigned int dest_buffer_size) { +bool keydb_get_volume_luks_passphrase(const volume_entry_t *volume, char *dest, unsigned int dest_buffer_size) { return ascii_encode(dest, dest_buffer_size, volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw)); } -bool keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase) { +bool keydb_write(const 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 */ @@ -266,15 +266,15 @@ static bool passphrase_callback(char *buffer, unsigned int bufsize) { return query_passphrase("Database passphrase: ", buffer, bufsize); } -struct keydb_t* keydb_read(const char *filename) { +keydb_t* keydb_read(const char *filename) { struct decrypted_file_t decrypted_file = read_encrypted_file(filename, passphrase_callback); if (!decrypted_file.success) { 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).", filename, keydb->keydb_version, KEYDB_VERSION); + keydb_t *keydb = (keydb_t*)decrypted_file.data; + if (keydb->common.keydb_version != KEYDB_CURRENT_VERSION) { + log_msg(LLVL_ERROR, "keydb in %s could be read, but is of version %u (we expected %u).", filename, keydb->common.keydb_version, KEYDB_CURRENT_VERSION); OPENSSL_cleanse(decrypted_file.data, decrypted_file.data_length); free(decrypted_file.data); return NULL; diff --git a/keydb.h b/keydb.h index 0b1e38a..5194d51 100644 --- a/keydb.h +++ b/keydb.h @@ -30,48 +30,62 @@ #include "file_encryption.h" #include "global.h" -#define KEYDB_VERSION 2 +#define KEYDB_CURRENT_VERSION 2 -struct volume_entry_t { +enum volume_flag_t { + VOLUME_FLAG_ALLOW_DISCARD = (1 << 0), +}; + +struct keydb_common_header_t { + unsigned int keydb_version; +}; + +struct volume_entry_v2_t { uint8_t volume_uuid[16]; /* UUID of crypt_LUKS volume */ char devmapper_name[MAX_DEVMAPPER_NAME_LENGTH]; /* dmsetup name when unlocked. Zero-terminated string. */ uint8_t luks_passphrase_raw[LUKS_PASSPHRASE_RAW_SIZE_BYTES]; /* LUKS passphrase used to unlock volume; raw byte data */ }; -struct host_entry_t { +struct host_entry_v2_t { uint8_t host_uuid[16]; /* Host UUID */ char host_name[MAX_HOST_NAME_LENGTH]; /* Descriptive name of host */ uint8_t tls_psk[PSK_SIZE_BYTES]; /* Raw byte data of TLS-PSK that is used */ unsigned int volume_count; /* Number of volumes of this host */ - struct volume_entry_t volumes[MAX_VOLUMES_PER_HOST]; /* Volumes of this host */ + struct volume_entry_v2_t volumes[MAX_VOLUMES_PER_HOST]; /* Volumes of this host */ }; -struct keydb_t { - unsigned int keydb_version; +struct keydb_v2_t { + struct keydb_common_header_t common; bool server_database; unsigned int host_count; - struct host_entry_t hosts[]; + struct host_entry_v2_t hosts[]; }; + +typedef struct volume_entry_v2_t volume_entry_t; +typedef struct host_entry_v2_t host_entry_t; +typedef struct keydb_v2_t keydb_t; + + /*************** AUTO GENERATED SECTION FOLLOWS ***************/ -struct keydb_t* keydb_new(void); -struct keydb_t* keydb_export_public(struct host_entry_t *host); -void keydb_free(struct keydb_t *keydb); -struct volume_entry_t* keydb_get_volume_by_name(struct host_entry_t *host, const char *devmapper_name); -struct host_entry_t* keydb_get_host_by_name(struct keydb_t *keydb, const char *host_name); -const struct volume_entry_t* keydb_get_volume_by_uuid(const struct host_entry_t *host, const uint8_t uuid[static 16]); -int keydb_get_host_index(const struct keydb_t *keydb, const struct host_entry_t *host); -int keydb_get_volume_index(const struct host_entry_t *host, const struct volume_entry_t *volume); -const struct host_entry_t* keydb_get_host_by_uuid(const struct keydb_t *keydb, const uint8_t uuid[static 16]); -bool keydb_add_host(struct keydb_t **keydb, const char *host_name); -bool keydb_del_host_by_name(struct keydb_t **keydb, const char *host_name); -bool keydb_rekey_host(struct host_entry_t *host); -struct volume_entry_t* keydb_add_volume(struct host_entry_t *host, const char *devmapper_name, const uint8_t volume_uuid[static 16]); -bool keydb_del_volume(struct host_entry_t *host, const char *devmapper_name); -bool keydb_rekey_volume(struct volume_entry_t *volume); -bool keydb_get_volume_luks_passphrase(const struct volume_entry_t *volume, char *dest, unsigned int dest_buffer_size); -bool keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase); -struct keydb_t* keydb_read(const char *filename); +keydb_t* keydb_new(void); +keydb_t* keydb_export_public(host_entry_t *host); +void keydb_free(keydb_t *keydb); +volume_entry_t* keydb_get_volume_by_name(host_entry_t *host, const char *devmapper_name); +host_entry_t* keydb_get_host_by_name(keydb_t *keydb, const char *host_name); +const volume_entry_t* keydb_get_volume_by_uuid(const host_entry_t *host, const uint8_t uuid[static 16]); +int keydb_get_host_index(const keydb_t *keydb, const host_entry_t *host); +int keydb_get_volume_index(const host_entry_t *host, const volume_entry_t *volume); +const host_entry_t* keydb_get_host_by_uuid(const keydb_t *keydb, const uint8_t uuid[static 16]); +bool keydb_add_host(keydb_t **keydb, const char *host_name); +bool keydb_del_host_by_name(keydb_t **keydb, const char *host_name); +bool keydb_rekey_host(host_entry_t *host); +volume_entry_t* keydb_add_volume(host_entry_t *host, const char *devmapper_name, const uint8_t volume_uuid[static 16]); +bool keydb_del_volume(host_entry_t *host, const char *devmapper_name); +bool keydb_rekey_volume(volume_entry_t *volume); +bool keydb_get_volume_luks_passphrase(const volume_entry_t *volume, char *dest, unsigned int dest_buffer_size); +bool keydb_write(const keydb_t *keydb, const char *filename, const char *passphrase); +keydb_t* keydb_read(const char *filename); /*************** AUTO GENERATED SECTION ENDS ***************/ #endif diff --git a/server.c b/server.c index 3e80709..40002b0 100644 --- a/server.c +++ b/server.c @@ -52,7 +52,7 @@ #include "vaulted_keydb.h" struct keyserver_t { - struct keydb_t* keydb; + keydb_t* keydb; struct vaulted_keydb_t *vaulted_keydb; struct generic_tls_ctx_t gctx; const struct pgmopts_server_t *opts; @@ -61,14 +61,14 @@ struct keyserver_t { struct client_thread_ctx_t { struct generic_tls_ctx_t *gctx; - const struct keydb_t *keydb; + const keydb_t *keydb; struct vaulted_keydb_t *vaulted_keydb; - const struct host_entry_t *host; + const host_entry_t *host; int fd; }; struct udp_listen_thread_ctx_t { - const struct keydb_t *keydb; + const keydb_t *keydb; int udp_sd; unsigned int port; }; @@ -165,7 +165,7 @@ static void client_handler_thread(void *vctx) { * client by filling the UUID fields */ struct msg_t msgs[client->host->volume_count]; for (unsigned int i = 0; i < client->host->volume_count; i++) { - const struct volume_entry_t *volume = &client->host->volumes[i]; + const volume_entry_t *volume = &client->host->volumes[i]; memcpy(msgs[i].volume_uuid, volume->volume_uuid, 16); } diff --git a/vaulted_keydb.c b/vaulted_keydb.c index e7a197d..ad61e2f 100644 --- a/vaulted_keydb.c +++ b/vaulted_keydb.c @@ -35,9 +35,9 @@ static struct luks_passphrase_vault_entry_t *vaulted_keydb_get_luks_passphrase_f return ((struct luks_passphrase_vault_entry_t*)vkeydb->luks_passphrase_vault->data) + host_index; } -static void move_data_into_vault(struct vaulted_keydb_t *dest, struct keydb_t *src) { +static void move_data_into_vault(struct vaulted_keydb_t *dest, keydb_t *src) { for (unsigned int i = 0; i < src->host_count; i++) { - struct host_entry_t *host = &src->hosts[i]; + host_entry_t *host = &src->hosts[i]; /* Copy over TLS-PSK and remove original */ struct tls_psk_vault_entry_t *dest_tls_psk = vaulted_keydb_get_tls_psk_for_hostindex(dest, i); @@ -47,14 +47,14 @@ static void move_data_into_vault(struct vaulted_keydb_t *dest, struct keydb_t *s /* Copy over all LUKS keys and remove originals */ struct luks_passphrase_vault_entry_t *dest_luks_passphrase = vaulted_keydb_get_luks_passphrase_for_hostindex(dest, i); for (unsigned int j = 0; j < host->volume_count; j++) { - struct volume_entry_t *volume = &host->volumes[j]; + volume_entry_t *volume = &host->volumes[j]; memcpy(&dest_luks_passphrase->volumes[j].luks_passphrase_raw, volume->luks_passphrase_raw, LUKS_PASSPHRASE_RAW_SIZE_BYTES); OPENSSL_cleanse(volume->luks_passphrase_raw, LUKS_PASSPHRASE_RAW_SIZE_BYTES); } } } -bool vaulted_keydb_get_tls_psk(struct vaulted_keydb_t *vaulted_keydb, uint8_t dest[PSK_SIZE_BYTES], const struct host_entry_t *host) { +bool vaulted_keydb_get_tls_psk(struct vaulted_keydb_t *vaulted_keydb, uint8_t dest[PSK_SIZE_BYTES], const host_entry_t *host) { int host_index = keydb_get_host_index(vaulted_keydb->keydb, host); if (host_index < 0) { log_msg(LLVL_FATAL, "Unable to retrieve host index for vaulted key db entry."); @@ -83,7 +83,7 @@ bool vaulted_keydb_get_tls_psk(struct vaulted_keydb_t *vaulted_keydb, uint8_t de return true; } -bool vaulted_keydb_get_volume_luks_passphases_raw(struct vaulted_keydb_t *vaulted_keydb, void (*copy_callback)(void *vctx, unsigned int volume_index, const void *source), void *copy_ctx, const struct host_entry_t *host) { +bool vaulted_keydb_get_volume_luks_passphases_raw(struct vaulted_keydb_t *vaulted_keydb, void (*copy_callback)(void *vctx, unsigned int volume_index, const void *source), void *copy_ctx, const host_entry_t *host) { int host_index = keydb_get_host_index(vaulted_keydb->keydb, host); if (host_index < 0) { log_msg(LLVL_FATAL, "Unable to retrieve host index for vaulted key db entry."); @@ -112,7 +112,7 @@ bool vaulted_keydb_get_volume_luks_passphases_raw(struct vaulted_keydb_t *vaulte return true; } -struct vaulted_keydb_t *vaulted_keydb_new(struct keydb_t *keydb) { +struct vaulted_keydb_t *vaulted_keydb_new(keydb_t *keydb) { struct vaulted_keydb_t *vaulted_keydb = calloc(1, sizeof(struct vaulted_keydb_t)); if (!vaulted_keydb) { log_msg(LLVL_FATAL, "Unable to calloc(3) vaulted keydb"); diff --git a/vaulted_keydb.h b/vaulted_keydb.h index 932146f..17c0c12 100644 --- a/vaulted_keydb.h +++ b/vaulted_keydb.h @@ -38,15 +38,15 @@ struct luks_passphrase_vault_entry_t { }; struct vaulted_keydb_t { - struct keydb_t *keydb; + keydb_t *keydb; struct vault_t *tls_psk_vault; struct vault_t *luks_passphrase_vault; }; /*************** AUTO GENERATED SECTION FOLLOWS ***************/ -bool vaulted_keydb_get_tls_psk(struct vaulted_keydb_t *vaulted_keydb, uint8_t dest[PSK_SIZE_BYTES], const struct host_entry_t *host); -bool vaulted_keydb_get_volume_luks_passphases_raw(struct vaulted_keydb_t *vaulted_keydb, void (*copy_callback)(void *ctx, unsigned int volume_index, const void *source), void *copy_ctx, const struct host_entry_t *host); -struct vaulted_keydb_t *vaulted_keydb_new(struct keydb_t *keydb); +bool vaulted_keydb_get_tls_psk(struct vaulted_keydb_t *vaulted_keydb, uint8_t dest[PSK_SIZE_BYTES], const host_entry_t *host); +bool vaulted_keydb_get_volume_luks_passphases_raw(struct vaulted_keydb_t *vaulted_keydb, void (*copy_callback)(void *ctx, unsigned int volume_index, const void *source), void *copy_ctx, const host_entry_t *host); +struct vaulted_keydb_t *vaulted_keydb_new(keydb_t *keydb); void vaulted_keydb_free(struct vaulted_keydb_t *vaulted_keydb); /*************** AUTO GENERATED SECTION ENDS ***************/