mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-13 11:50:10 +01:00
Allow linking VK to a user-specified keyring.
Add a new API crypt_set_keyring_to_link nad CLI option --link-vk-to-keyring. This allows the user to specify ID of the keyring where the VK should be linked.
This commit is contained in:
@@ -3028,6 +3028,14 @@ void *crypt_safe_realloc(void *data, size_t size);
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Link the volume key to the specified keyring.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param keyring_to_link_vk the ID of the keyring in which volume key should be linked
|
||||
*/
|
||||
void crypt_set_keyring_to_link(struct crypt_device *cd, int keyring_to_link_vk);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -174,5 +174,6 @@ CRYPTSETUP_2.7 {
|
||||
crypt_get_hw_encryption_key_size;
|
||||
crypt_keyslot_context_init_by_keyring;
|
||||
crypt_resume_by_keyslot_context;
|
||||
crypt_set_keyring_to_link;
|
||||
crypt_wipe_hw_opal;
|
||||
} CRYPTSETUP_2.6;
|
||||
|
||||
20
lib/setup.c
20
lib/setup.c
@@ -60,6 +60,9 @@ struct crypt_device {
|
||||
/* global context scope settings */
|
||||
unsigned key_in_keyring:1;
|
||||
|
||||
bool link_vk_to_keyring;
|
||||
int keyring_to_link_vk;
|
||||
|
||||
uint64_t data_offset;
|
||||
uint64_t metadata_size; /* Used in LUKS2 format */
|
||||
uint64_t keyslots_size; /* Used in LUKS2 format */
|
||||
@@ -7206,6 +7209,15 @@ int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key
|
||||
} else
|
||||
crypt_set_key_in_keyring(cd, 1);
|
||||
|
||||
if (!r && cd->link_vk_to_keyring) {
|
||||
log_dbg(cd, "Linking volume key to the specified keyring");
|
||||
r = keyring_link_key_to_keyring(LOGON_KEY, vk->key_description, cd->keyring_to_link_vk);
|
||||
if (r) {
|
||||
log_err(cd, _("Failed to link key to the specified keyring."));
|
||||
log_dbg(cd, "The keyring_link_key_to_keyring function failed (error %d).", r);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -7241,6 +7253,14 @@ void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *
|
||||
crypt_set_key_in_keyring(cd, 0);
|
||||
}
|
||||
|
||||
void crypt_set_keyring_to_link(struct crypt_device *cd, int keyring_to_link_vk)
|
||||
{
|
||||
if (cd) {
|
||||
cd->link_vk_to_keyring = true;
|
||||
cd->keyring_to_link_vk = keyring_to_link_vk;
|
||||
}
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks)
|
||||
{
|
||||
|
||||
@@ -71,6 +71,12 @@ static long keyctl_read(key_serial_t key, char *buffer, size_t buflen)
|
||||
return syscall(__NR_keyctl, KEYCTL_READ, key, buffer, buflen);
|
||||
}
|
||||
|
||||
/* keyctl_link */
|
||||
static long keyctl_link(key_serial_t key, key_serial_t keyring)
|
||||
{
|
||||
return syscall(__NR_keyctl, KEYCTL_LINK, key, keyring);
|
||||
}
|
||||
|
||||
/* keyctl_unlink */
|
||||
static long keyctl_unlink(key_serial_t key, key_serial_t keyring)
|
||||
{
|
||||
@@ -180,6 +186,33 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int keyring_link_key_to_keyring_key_type(const char *type_name, const char *key_desc,
|
||||
key_serial_t keyring_to_link)
|
||||
{
|
||||
#ifdef KERNEL_KEYRING
|
||||
long r;
|
||||
key_serial_t kid;
|
||||
|
||||
if (!type_name || !key_desc)
|
||||
return -EINVAL;
|
||||
|
||||
do
|
||||
kid = request_key(type_name, key_desc, NULL, 0);
|
||||
while (kid < 0 && errno == EINTR);
|
||||
|
||||
if (kid < 0)
|
||||
return 0;
|
||||
|
||||
r = keyctl_link(kid, keyring_to_link);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int keyring_revoke_and_unlink_key_type(const char *type_name, const char *key_desc)
|
||||
{
|
||||
#ifdef KERNEL_KEYRING
|
||||
@@ -216,6 +249,11 @@ const char *key_type_name(key_type_t type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int keyring_link_key_to_keyring(key_type_t ktype, const char *key_desc, key_serial_t keyring_to_link)
|
||||
{
|
||||
return keyring_link_key_to_keyring_key_type(key_type_name(ktype), key_desc, keyring_to_link);
|
||||
}
|
||||
|
||||
int keyring_revoke_and_unlink_key(key_type_t ktype, const char *key_desc)
|
||||
{
|
||||
return keyring_revoke_and_unlink_key_type(key_type_name(ktype), key_desc);
|
||||
|
||||
@@ -51,5 +51,6 @@ int keyring_add_key_in_user_keyring(
|
||||
size_t key_size);
|
||||
|
||||
int keyring_revoke_and_unlink_key(key_type_t ktype, const char *key_desc);
|
||||
int keyring_link_key_to_keyring(key_type_t ktype, const char *key_desc, int keyring_to_link);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1654,6 +1654,9 @@ static int action_open_luks(void)
|
||||
|
||||
set_activation_flags(&activate_flags);
|
||||
|
||||
if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID))
|
||||
crypt_set_keyring_to_link(cd, ARG_INT32(OPT_LINK_VK_TO_KEYRING_ID));
|
||||
|
||||
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID)) {
|
||||
keysize = crypt_get_volume_key_size(cd);
|
||||
if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
|
||||
@@ -2509,6 +2512,9 @@ static int action_luksResume(void)
|
||||
return r;
|
||||
|
||||
r = -EINVAL;
|
||||
if (ARG_SET(OPT_LINK_VK_TO_KEYRING_ID))
|
||||
crypt_set_keyring_to_link(cd, ARG_INT32(OPT_LINK_VK_TO_KEYRING_ID));
|
||||
|
||||
if (!isLUKS(crypt_get_type(cd))) {
|
||||
log_err(_("%s is not active LUKS device name or header is missing."), action_argv[0]);
|
||||
goto out;
|
||||
@@ -3655,6 +3661,11 @@ int main(int argc, const char **argv)
|
||||
_("PBKDF forced iterations cannot be combined with iteration time option."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (ARG_SET(OPT_DISABLE_KEYRING_ID) && ARG_SET(OPT_LINK_VK_TO_KEYRING_ID))
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
_("Cannot link volume key to a keyring when keyring is disabled."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (ARG_SET(OPT_DEBUG_ID) || ARG_SET(OPT_DEBUG_JSON_ID)) {
|
||||
crypt_set_debug_level(ARG_SET(OPT_DEBUG_JSON_ID)? CRYPT_DEBUG_JSON : CRYPT_DEBUG_ALL);
|
||||
dbg_version_and_cmd(argc, argv);
|
||||
|
||||
@@ -111,6 +111,8 @@ ARG(OPT_KEYSLOT_KEY_SIZE, '\0', POPT_ARG_STRING, N_("LUKS2 keyslot: The size of
|
||||
|
||||
ARG(OPT_LABEL, '\0', POPT_ARG_STRING, N_("Set label for the LUKS2 device"), NULL, CRYPT_ARG_STRING, {}, OPT_LABEL_ACTIONS)
|
||||
|
||||
ARG(OPT_LINK_VK_TO_KEYRING, '\0', POPT_ARG_STRING, N_("Set keyring where to link volume key"), NULL, CRYPT_ARG_INT32, {}, OPT_LINK_VK_TO_KEYRING_ACTIONS)
|
||||
|
||||
ARG(OPT_LUKS2_KEYSLOTS_SIZE, '\0', POPT_ARG_STRING, N_("LUKS2 header keyslots area size"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_LUKS2_KEYSLOTS_SIZE_ACTIONS)
|
||||
|
||||
ARG(OPT_LUKS2_METADATA_SIZE, '\0', POPT_ARG_STRING, N_("LUKS2 header metadata area size"), N_("bytes"), CRYPT_ARG_UINT64, {}, OPT_LUKS2_METADATA_SIZE_ACTIONS)
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
#define OPT_NEW_KEY_SLOT_ACTIONS { ADDKEY_ACTION }
|
||||
#define OPT_NEW_TOKEN_ID_ACTIONS { ADDKEY_ACTION }
|
||||
#define OPT_LABEL_ACTIONS { CONFIG_ACTION, FORMAT_ACTION, REENCRYPT_ACTION }
|
||||
#define OPT_LINK_VK_TO_KEYRING_ACTIONS { OPEN_ACTION, RESUME_ACTION }
|
||||
#define OPT_LUKS2_KEYSLOTS_SIZE_ACTIONS { REENCRYPT_ACTION, FORMAT_ACTION }
|
||||
#define OPT_LUKS2_METADATA_SIZE_ACTIONS { REENCRYPT_ACTION, FORMAT_ACTION }
|
||||
#define OPT_OFFSET_ACTIONS { OPEN_ACTION, REENCRYPT_ACTION, FORMAT_ACTION }
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
#define OPT_NO_WIPE "no-wipe"
|
||||
#define OPT_WIPE "wipe"
|
||||
#define OPT_LABEL "label"
|
||||
#define OPT_LINK_VK_TO_KEYRING "link-vk-to-keyring"
|
||||
#define OPT_LUKS2_KEYSLOTS_SIZE "luks2-keyslots-size"
|
||||
#define OPT_LUKS2_METADATA_SIZE "luks2-metadata-size"
|
||||
#define OPT_MASTER_KEY_FILE "master-key-file"
|
||||
|
||||
Reference in New Issue
Block a user