Move keyring utilities to separate file.

This commit is contained in:
Milan Broz
2024-11-15 20:44:57 +01:00
parent ae4b4ff4d7
commit 42e85571df
6 changed files with 176 additions and 155 deletions

View File

@@ -53,5 +53,6 @@ src/utils_reencrypt.c
src/utils_reencrypt_luks1.c src/utils_reencrypt_luks1.c
src/utils_blockdev.c src/utils_blockdev.c
src/utils_args.c src/utils_args.c
src/utils_key_description.c
tokens/ssh/cryptsetup-ssh.c tokens/ssh/cryptsetup-ssh.c
tokens/ssh/ssh-utils.c tokens/ssh/ssh-utils.c

View File

@@ -17,6 +17,7 @@ cryptsetup_SOURCES = \
src/utils_reencrypt.c \ src/utils_reencrypt.c \
src/utils_reencrypt_luks1.c \ src/utils_reencrypt_luks1.c \
src/utils_progress.c \ src/utils_progress.c \
src/utils_key_description.c \
src/cryptsetup.c \ src/cryptsetup.c \
src/cryptsetup.h \ src/cryptsetup.h \
src/cryptsetup_args.h \ src/cryptsetup_args.h \

View File

@@ -1774,154 +1774,6 @@ static int action_luksFormat(void)
return luksFormat(NULL, NULL, NULL); return luksFormat(NULL, NULL, NULL);
} }
static int parse_vk_description(const char *key_description, char **ret_key_description)
{
char *tmp;
int r;
assert(key_description);
assert(ret_key_description);
/* apply default key type */
if (*key_description != '%')
r = asprintf(&tmp, "%%user:%s", key_description) < 0 ? -EINVAL : 0;
else
r = (tmp = strdup(key_description)) ? 0 : -ENOMEM;
if (!r)
*ret_key_description = tmp;
return r;
}
static int parse_single_vk_and_keyring_description(
struct crypt_device *cd,
char *keyring_key_description, char **keyring_part_out, char
**key_part_out, char **type_part_out)
{
int r = -EINVAL;
char *endp, *sep, *key_part, *type_part = NULL;
char *key_part_copy = NULL, *type_part_copy = NULL, *keyring_part = NULL;
if (!cd || !keyring_key_description)
return -EINVAL;
/* "::" is separator between keyring specification a key description */
key_part = strstr(keyring_key_description, "::");
if (!key_part)
goto out;
*key_part = '\0';
key_part = key_part + 2;
if (*key_part == '%') {
type_part = key_part + 1;
sep = strstr(type_part, ":");
if (!sep)
goto out;
*sep = '\0';
key_part = sep + 1;
}
if (*keyring_key_description == '%') {
keyring_key_description = strstr(keyring_key_description, ":");
if (!keyring_key_description)
goto out;
log_verbose(_("Type specification in --link-vk-to-keyring keyring specification is ignored."));
keyring_key_description++;
}
(void)strtol(keyring_key_description, &endp, 0);
r = 0;
if (*keyring_key_description == '@' || !*endp)
keyring_part = strdup(keyring_key_description);
else
r = asprintf(&keyring_part, "%%:%s", keyring_key_description);
if (!keyring_part || r < 0) {
r = -ENOMEM;
goto out;
}
if (!(key_part_copy = strdup(key_part))) {
r = -ENOMEM;
goto out;
}
if (type_part && !(type_part_copy = strdup(type_part)))
r = -ENOMEM;
out:
if (r < 0) {
free(keyring_part);
free(key_part_copy);
free(type_part_copy);
} else {
*keyring_part_out = keyring_part;
*key_part_out = key_part_copy;
*type_part_out = type_part_copy;
}
return r;
}
static int parse_vk_and_keyring_description(
struct crypt_device *cd,
char **keyring_key_descriptions,
int keyring_key_links_count)
{
int r = 0;
char *keyring_part_out1 = NULL, *key_part_out1 = NULL, *type_part_out1 = NULL;
char *keyring_part_out2 = NULL, *key_part_out2 = NULL, *type_part_out2 = NULL;
if (keyring_key_links_count > 0) {
r = parse_single_vk_and_keyring_description(cd,
keyring_key_descriptions[0],
&keyring_part_out1, &key_part_out1,
&type_part_out1);
if (r < 0)
goto out;
}
if (keyring_key_links_count > 1) {
r = parse_single_vk_and_keyring_description(cd,
keyring_key_descriptions[1],
&keyring_part_out2, &key_part_out2,
&type_part_out2);
if (r < 0)
goto out;
if ((type_part_out1 && type_part_out2) && strcmp(type_part_out1, type_part_out2)) {
log_err(_("Key types have to be the same for both volume keys."));
r = -EINVAL;
goto out;
}
if ((keyring_part_out1 && keyring_part_out2) && strcmp(keyring_part_out1, keyring_part_out2)) {
log_err(_("Both volume keys have to be linked to the same keyring."));
r = -EINVAL;
goto out;
}
}
if (keyring_key_links_count > 0) {
r = crypt_set_keyring_to_link(cd, key_part_out1, key_part_out2,
type_part_out1, keyring_part_out1);
if (r == -EAGAIN)
log_err(_("You need to supply more key names."));
}
out:
if (r == -EINVAL)
log_err(_("Invalid --link-vk-to-keyring value."));
free(keyring_part_out1);
free(key_part_out1);
free(type_part_out1);
free(keyring_part_out2);
free(key_part_out2);
free(type_part_out2);
return r;
}
static int action_open_luks(void) static int action_open_luks(void)
{ {
struct crypt_active_device cad; struct crypt_active_device cad;
@@ -1985,7 +1837,7 @@ static int action_open_luks(void)
} }
if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID)) { if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID)) {
r = parse_vk_and_keyring_description(cd, keyring_links, keyring_links_count); r = tools_parse_vk_and_keyring_description(cd, keyring_links, keyring_links_count);
if (r < 0) if (r < 0)
goto out; goto out;
} }
@@ -2006,7 +1858,7 @@ static int action_open_luks(void)
key, keysize, activate_flags); key, keysize, activate_flags);
} else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) { } else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
if (vks_in_keyring_count == 1) { if (vks_in_keyring_count == 1) {
r = parse_vk_description(vks_in_keyring[0], &vk_description_activation1); r = tools_parse_vk_description(vks_in_keyring[0], &vk_description_activation1);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1); r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1);
@@ -2014,10 +1866,10 @@ static int action_open_luks(void)
goto out; goto out;
r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT, kc1, CRYPT_ANY_SLOT, NULL, activate_flags); r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT, kc1, CRYPT_ANY_SLOT, NULL, activate_flags);
} else if (vks_in_keyring_count == 2) { } else if (vks_in_keyring_count == 2) {
r = parse_vk_description(vks_in_keyring[0], &vk_description_activation1); r = tools_parse_vk_description(vks_in_keyring[0], &vk_description_activation1);
if (r < 0) if (r < 0)
goto out; goto out;
r = parse_vk_description(vks_in_keyring[1], &vk_description_activation2); r = tools_parse_vk_description(vks_in_keyring[1], &vk_description_activation2);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1); r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1);
@@ -2445,7 +2297,7 @@ static int action_luksAddKey(void)
r = crypt_keyslot_context_init_by_volume_key(cd, key, keysize, &kc); r = crypt_keyslot_context_init_by_volume_key(cd, key, keysize, &kc);
crypt_safe_free(key); crypt_safe_free(key);
} else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) { } else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
r = parse_vk_description(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID), &vk_description); r = tools_parse_vk_description(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID), &vk_description);
if (!r) { if (!r) {
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description, &kc); r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description, &kc);
free(vk_description); free(vk_description);
@@ -2874,7 +2726,7 @@ static int action_luksResume(void)
return r; return r;
if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID)) { if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID)) {
r = parse_vk_and_keyring_description(cd, keyring_links, keyring_links_count); r = tools_parse_vk_and_keyring_description(cd, keyring_links, keyring_links_count);
if (r < 0) if (r < 0)
goto out; goto out;
} }
@@ -2919,7 +2771,7 @@ static int action_luksResume(void)
goto out; goto out;
if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) { if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
r = parse_vk_description(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID), &vk_description_activation); r = tools_parse_vk_description(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID), &vk_description_activation);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation, &kc); r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation, &kc);

View File

@@ -117,6 +117,13 @@ int tools_lookup_crypt_device(struct crypt_device *cd, const char *type,
/* each utility is required to implement it */ /* each utility is required to implement it */
void tools_cleanup(void); void tools_cleanup(void);
/* keyring helpers */
int tools_parse_vk_description(const char *key_description, char **ret_key_description);
int tools_parse_vk_and_keyring_description(
struct crypt_device *cd,
char **keyring_key_descriptions,
int keyring_key_links_count);
/* Log */ /* Log */
#define log_dbg(x...) crypt_logf(NULL, CRYPT_LOG_DEBUG, x) #define log_dbg(x...) crypt_logf(NULL, CRYPT_LOG_DEBUG, x)
#define log_std(x...) crypt_logf(NULL, CRYPT_LOG_NORMAL, x) #define log_std(x...) crypt_logf(NULL, CRYPT_LOG_NORMAL, x)

View File

@@ -11,6 +11,7 @@ if get_option('cryptsetup')
'utils_reencrypt.c', 'utils_reencrypt.c',
'utils_reencrypt_luks1.c', 'utils_reencrypt_luks1.c',
'utils_tools.c', 'utils_tools.c',
'utils_key_description.c',
) )
cryptsetup_files += lib_tools_files cryptsetup_files += lib_tools_files
cryptsetup_deps = [ cryptsetup_deps = [

159
src/utils_key_description.c Normal file
View File

@@ -0,0 +1,159 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Password quality check wrapper
*
* Copyright (C) 2023-2024 Red Hat, Inc. All rights reserved.
* Copyright (C) 2023-2024 Ondrej Kozina
* Copyright (C) 2023-2024 Milan Broz
*/
#include "cryptsetup.h"
#include <assert.h>
int tools_parse_vk_description(const char *key_description, char **ret_key_description)
{
char *tmp;
int r;
assert(key_description);
assert(ret_key_description);
/* apply default key type */
if (*key_description != '%')
r = asprintf(&tmp, "%%user:%s", key_description) < 0 ? -EINVAL : 0;
else
r = (tmp = strdup(key_description)) ? 0 : -ENOMEM;
if (!r)
*ret_key_description = tmp;
return r;
}
static int parse_single_vk_and_keyring_description(
struct crypt_device *cd,
char *keyring_key_description, char **keyring_part_out, char
**key_part_out, char **type_part_out)
{
int r = -EINVAL;
char *endp, *sep, *key_part, *type_part = NULL;
char *key_part_copy = NULL, *type_part_copy = NULL, *keyring_part = NULL;
if (!cd || !keyring_key_description)
return -EINVAL;
/* "::" is separator between keyring specification a key description */
key_part = strstr(keyring_key_description, "::");
if (!key_part)
goto out;
*key_part = '\0';
key_part = key_part + 2;
if (*key_part == '%') {
type_part = key_part + 1;
sep = strstr(type_part, ":");
if (!sep)
goto out;
*sep = '\0';
key_part = sep + 1;
}
if (*keyring_key_description == '%') {
keyring_key_description = strstr(keyring_key_description, ":");
if (!keyring_key_description)
goto out;
log_verbose(_("Type specification in --link-vk-to-keyring keyring specification is ignored."));
keyring_key_description++;
}
(void)strtol(keyring_key_description, &endp, 0);
r = 0;
if (*keyring_key_description == '@' || !*endp)
keyring_part = strdup(keyring_key_description);
else
r = asprintf(&keyring_part, "%%:%s", keyring_key_description);
if (!keyring_part || r < 0) {
r = -ENOMEM;
goto out;
}
if (!(key_part_copy = strdup(key_part))) {
r = -ENOMEM;
goto out;
}
if (type_part && !(type_part_copy = strdup(type_part)))
r = -ENOMEM;
out:
if (r < 0) {
free(keyring_part);
free(key_part_copy);
free(type_part_copy);
} else {
*keyring_part_out = keyring_part;
*key_part_out = key_part_copy;
*type_part_out = type_part_copy;
}
return r;
}
int tools_parse_vk_and_keyring_description(
struct crypt_device *cd,
char **keyring_key_descriptions,
int keyring_key_links_count)
{
int r = 0;
char *keyring_part_out1 = NULL, *key_part_out1 = NULL, *type_part_out1 = NULL;
char *keyring_part_out2 = NULL, *key_part_out2 = NULL, *type_part_out2 = NULL;
if (keyring_key_links_count > 0) {
r = parse_single_vk_and_keyring_description(cd,
keyring_key_descriptions[0],
&keyring_part_out1, &key_part_out1,
&type_part_out1);
if (r < 0)
goto out;
}
if (keyring_key_links_count > 1) {
r = parse_single_vk_and_keyring_description(cd,
keyring_key_descriptions[1],
&keyring_part_out2, &key_part_out2,
&type_part_out2);
if (r < 0)
goto out;
if ((type_part_out1 && type_part_out2) && strcmp(type_part_out1, type_part_out2)) {
log_err(_("Key types have to be the same for both volume keys."));
r = -EINVAL;
goto out;
}
if ((keyring_part_out1 && keyring_part_out2) && strcmp(keyring_part_out1, keyring_part_out2)) {
log_err(_("Both volume keys have to be linked to the same keyring."));
r = -EINVAL;
goto out;
}
}
if (keyring_key_links_count > 0) {
r = crypt_set_keyring_to_link(cd, key_part_out1, key_part_out2,
type_part_out1, keyring_part_out1);
if (r == -EAGAIN)
log_err(_("You need to supply more key names."));
}
out:
if (r == -EINVAL)
log_err(_("Invalid --link-vk-to-keyring value."));
free(keyring_part_out1);
free(key_part_out1);
free(type_part_out1);
free(keyring_part_out2);
free(key_part_out2);
free(type_part_out2);
return r;
}