diff --git a/keydb.c b/keydb.c index a655a3d..465ab77 100644 --- a/keydb.c +++ b/keydb.c @@ -80,29 +80,24 @@ void keydb_free(struct keydb_t *keydb) { } } -static int keydb_get_volume_index_by_name(struct host_entry_t *host, const char *devmapper_name) { +struct volume_entry_t* keydb_get_volume_by_name(struct 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]; if (!strncasecmp(volume->devmapper_name, devmapper_name, sizeof(volume->devmapper_name) - 1)) { - return i; + return volume; } } - return -1; + return NULL; } -static int keydb_get_host_index_by_name(struct keydb_t *keydb, const char *host_name) { +struct host_entry_t* keydb_get_host_by_name(struct 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]; if (!strncasecmp(host->host_name, host_name, sizeof(host->host_name) - 1)) { - return i; + return host; } } - return -1; -} - -struct volume_entry_t* keydb_get_volume_by_name(struct host_entry_t *host, const char *devmapper_name) { - const int index = keydb_get_volume_index_by_name(host, devmapper_name); - return (index >= 0) ? &host->volumes[index] : NULL; + return NULL; } const struct volume_entry_t* keydb_get_volume_by_uuid(const struct host_entry_t *host, const uint8_t uuid[static 16]) { @@ -115,19 +110,24 @@ const struct volume_entry_t* keydb_get_volume_by_uuid(const struct host_entry_t return NULL; } -int keydb_get_volume_index(const struct host_entry_t *host, const struct volume_entry_t *volume) { - int offset = volume - host->volumes; - if (offset < 0) { +int keydb_get_host_index(const struct keydb_t *keydb, const struct host_entry_t *host) { + int index = host - keydb->hosts; + if (index < 0) { return -1; - } else if ((unsigned int)offset >= host->volume_count) { + } else if ((unsigned int)index >= keydb ->host_count) { return -1; } - return offset; + return index; } -struct host_entry_t* keydb_get_host_by_name(struct keydb_t *keydb, const char *host_name) { - const int index = keydb_get_host_index_by_name(keydb, host_name); - return (index >= 0) ? &keydb->hosts[index] : NULL; +int keydb_get_volume_index(const struct host_entry_t *host, const struct volume_entry_t *volume) { + int index = volume - host->volumes; + if (index < 0) { + return -1; + } else if ((unsigned int)index >= host->volume_count) { + return -1; + } + return index; } const struct host_entry_t* keydb_get_host_by_uuid(const struct keydb_t *keydb, const uint8_t uuid[static 16]) { @@ -176,12 +176,18 @@ 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) { struct keydb_t *old_keydb = *keydb; - int host_index = keydb_get_host_index_by_name(old_keydb, host_name); - if (host_index == -1) { + struct 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; } + int host_index = keydb_get_host_index(old_keydb, host); + if (host_index < 0) { + log_msg(LLVL_FATAL, "Fatal error determining host index of \"%s\" for host \"%s\".", host_name); + return false; + } + /* 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); old_keydb->host_count--; @@ -219,11 +225,16 @@ struct volume_entry_t* keydb_add_volume(struct host_entry_t *host, const char *d } bool keydb_del_volume(struct host_entry_t *host, const char *devmapper_name) { - int index = keydb_get_volume_index_by_name(host, devmapper_name); - if (index == -1) { + struct 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; } + int index = keydb_get_volume_index(host, volume); + if (index < 0) { + 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)) { log_msg(LLVL_ERROR, "Failed to remove \"%s\" of host \"%s\".", devmapper_name, host->host_name); return false; diff --git a/keydb.h b/keydb.h index e62855c..0b1e38a 100644 --- a/keydb.h +++ b/keydb.h @@ -58,9 +58,10 @@ 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); -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_volume_index(const struct host_entry_t *host, const struct volume_entry_t *volume); 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); diff --git a/vaulted_keydb.c b/vaulted_keydb.c index a84e492..6f0955c 100644 --- a/vaulted_keydb.c +++ b/vaulted_keydb.c @@ -35,7 +35,7 @@ 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 copy_data_into_vault(struct vaulted_keydb_t *dest, struct keydb_t *src) { +static void move_data_into_vault(struct vaulted_keydb_t *dest, struct keydb_t *src) { for (unsigned int i = 0; i < src->host_count; i++) { struct host_entry_t *host = &src->hosts[i]; @@ -54,15 +54,67 @@ static void copy_data_into_vault(struct vaulted_keydb_t *dest, struct keydb_t *s } } -static void erase_key_data_from_keydb(struct keydb_t *keydb) { - for (unsigned int i = 0; i < keydb->host_count; i++) { - struct host_entry_t *host = &keydb->hosts[i]; - OPENSSL_cleanse(host->tls_psk, PSK_SIZE_BYTES); - for (unsigned int j = 0; j < host->volume_count; j++) { - struct volume_entry_t *volume = &host->volumes[j]; - 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) { + 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."); + return false; } + + /* Get a pointer into the vaulted structure */ + struct tls_psk_vault_entry_t *entry = vaulted_keydb_get_tls_psk_for_hostindex(vaulted_keydb, host_index); + + /* Then decrypt vault */ + if (!vault_open(vaulted_keydb->tls_psk_vault)) { + log_msg(LLVL_FATAL, "Unable to open TLS-PSK vault of vaulted key db entry."); + return false; + } + + /* Copy out the data we need */ + memcpy(dest, &entry->tls_psk, PSK_SIZE_BYTES); + + /* And close it back up */ + if (!vault_close(vaulted_keydb->tls_psk_vault)) { + OPENSSL_cleanse(dest, PSK_SIZE_BYTES); + log_msg(LLVL_FATAL, "Unable to close TLS-PSK vault of vaulted key db entry."); + return false; + } + + return true; +} + +bool vaulted_keydb_get_volume_luks_passphase_raw(struct vaulted_keydb_t *vaulted_keydb, uint8_t dest[LUKS_PASSPHRASE_RAW_SIZE_BYTES], const struct host_entry_t *host, const struct volume_entry_t *volume) { + 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."); + return false; + } + + int volume_index = keydb_get_volume_index(host, volume); + if (volume_index < 0) { + log_msg(LLVL_FATAL, "Unable to retrieve volume index for vaulted key db entry."); + return false; + } + + /* Get a pointer into the vaulted structure */ + struct luks_passphrase_vault_entry_t *entry = vaulted_keydb_get_luks_passphrase_for_hostindex(vaulted_keydb, host_index); + + /* Then decrypt vault */ + if (!vault_open(vaulted_keydb->luks_passphrase_vault)) { + log_msg(LLVL_FATAL, "Unable to open LUKS passphrase vault of vaulted key db entry."); + return false; + } + + /* Copy out the data we need */ + memcpy(dest, &entry->volumes[volume_index].luks_passphrase_raw, LUKS_PASSPHRASE_RAW_SIZE_BYTES); + + /* And close it back up */ + if (!vault_close(vaulted_keydb->luks_passphrase_vault)) { + OPENSSL_cleanse(dest, PSK_SIZE_BYTES); + log_msg(LLVL_FATAL, "Unable to close LUKS passphrase vault of vaulted key db entry."); + return false; + } + return true; } struct vaulted_keydb_t *vaulted_keydb_new(struct keydb_t *keydb) { @@ -74,25 +126,23 @@ struct vaulted_keydb_t *vaulted_keydb_new(struct keydb_t *keydb) { vaulted_keydb->keydb = keydb; - vaulted_keydb->tls_psk_vault = vault_init(sizeof(struct tls_psk_vault_entry_t) * keydb->host_count, 0.1); + vaulted_keydb->tls_psk_vault = vault_init(sizeof(struct tls_psk_vault_entry_t) * keydb->host_count, 0.025); if (!vaulted_keydb->tls_psk_vault) { log_msg(LLVL_FATAL, "Unable to create TLS-PSK vault"); vaulted_keydb_free(vaulted_keydb); return NULL; } - vaulted_keydb->luks_passphrase_vault = vault_init(sizeof(struct luks_passphrase_vault_entry_t) * keydb->host_count, 0.1); + vaulted_keydb->luks_passphrase_vault = vault_init(sizeof(struct luks_passphrase_vault_entry_t) * keydb->host_count, 0.025); if (!vaulted_keydb->luks_passphrase_vault) { log_msg(LLVL_FATAL, "Unable to create LUKS passphrase vault"); vaulted_keydb_free(vaulted_keydb); return NULL; } - /* Now copy over data from the original KeyDB */ - copy_data_into_vault(vaulted_keydb, keydb); - - /* Then erase original key data */ - erase_key_data_from_keydb(keydb); + /* Now move data from the original keydb into the vaulted keydb (erase + * original keys) */ + move_data_into_vault(vaulted_keydb, keydb); /* Finally, close the vaults */ if (!vault_close(vaulted_keydb->tls_psk_vault)) { diff --git a/vaulted_keydb.h b/vaulted_keydb.h index 1751e6b..99c7228 100644 --- a/vaulted_keydb.h +++ b/vaulted_keydb.h @@ -44,6 +44,8 @@ struct vaulted_keydb_t { }; /*************** 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_passphase_raw(struct vaulted_keydb_t *vaulted_keydb, uint8_t dest[LUKS_PASSPHRASE_RAW_SIZE_BYTES], const struct host_entry_t *host, const struct volume_entry_t *volume); struct vaulted_keydb_t *vaulted_keydb_new(struct keydb_t *keydb); void vaulted_keydb_free(struct vaulted_keydb_t *vaulted_keydb); /*************** AUTO GENERATED SECTION ENDS ***************/