mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 00:10:04 +01:00
Improve debug output for kernel keyring.
Add more context to possibly failing kernel keyring routines in log debug output. Mostly split debug output for errors while trying to search the kernel key by description and errors while trying to read/unlink the key by its id.
This commit is contained in:
committed by
Milan Broz
parent
cdce1d96f0
commit
6296e8d4f8
@@ -234,6 +234,14 @@ int crypt_get_integrity_tag_size(struct crypt_device *cd);
|
||||
int crypt_key_in_keyring(struct crypt_device *cd);
|
||||
void crypt_set_key_in_keyring(struct crypt_device *cd, unsigned key_in_keyring);
|
||||
int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key *vk);
|
||||
int crypt_keyring_get_user_key(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
char **key,
|
||||
size_t *key_size);
|
||||
int crypt_keyring_get_key_by_name(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
char **key,
|
||||
size_t *key_size);
|
||||
int crypt_use_keyring_for_vk(struct crypt_device *cd);
|
||||
void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype);
|
||||
void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks);
|
||||
|
||||
@@ -328,7 +328,8 @@ static int get_passphrase_by_keyring(struct crypt_device *cd,
|
||||
assert(r_passphrase_size);
|
||||
|
||||
if (!kc->i_passphrase) {
|
||||
r = keyring_get_user_key(kc->u.kr.key_description, &kc->i_passphrase, &kc->i_passphrase_size);
|
||||
r = crypt_keyring_get_user_key(cd, kc->u.kr.key_description,
|
||||
&kc->i_passphrase, &kc->i_passphrase_size);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Failed to read passphrase from keyring."));
|
||||
kc->error = -EINVAL;
|
||||
@@ -416,9 +417,10 @@ static int get_key_by_vk_in_keyring(struct crypt_device *cd,
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING);
|
||||
assert(r_vk);
|
||||
|
||||
r = keyring_find_and_get_key_by_name(kc->u.vk_kr.key_description, &kc->i_volume_key, &kc->i_volume_key_size);
|
||||
r = crypt_keyring_get_key_by_name(cd, kc->u.vk_kr.key_description,
|
||||
&kc->i_volume_key, &kc->i_volume_key_size);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Failed to read volume key from keyring."));
|
||||
log_err(cd, _("Failed to read volume key candidate from keyring."));
|
||||
kc->error = -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -3873,7 +3873,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = keyring_get_user_key(passphrase_description, &passphrase, &passphrase_size);
|
||||
r = crypt_keyring_get_user_key(cd, passphrase_description, &passphrase, &passphrase_size);
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Failed to read passphrase from keyring (error %d)."), r);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -40,14 +40,11 @@ int keyring_open(struct crypt_device *cd,
|
||||
|
||||
json_object_object_get_ex(jobj_token, "key_description", &jobj_key);
|
||||
|
||||
r = keyring_get_user_key(json_object_get_string(jobj_key), buffer, buffer_len);
|
||||
if (r == -ENOTSUP) {
|
||||
log_dbg(cd, "Kernel keyring features disabled.");
|
||||
r = crypt_keyring_get_user_key(cd, json_object_get_string(jobj_key), buffer, buffer_len);
|
||||
if (r == -ENOTSUP)
|
||||
return -ENOENT;
|
||||
} else if (r < 0) {
|
||||
log_dbg(cd, "keyring_get_user_key failed (error %d)", r);
|
||||
else if (r < 0)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
93
lib/setup.c
93
lib/setup.c
@@ -7297,6 +7297,74 @@ int crypt_volume_key_load_in_keyring(struct crypt_device *cd, struct volume_key
|
||||
return r;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_keyring_get_user_key(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
char **key,
|
||||
size_t *key_size)
|
||||
{
|
||||
int r;
|
||||
key_serial_t kid;
|
||||
|
||||
if (!key_description || !key || !key_size)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Requesting key %s (user type)", key_description);
|
||||
|
||||
kid = keyring_request_key_id(USER_KEY, key_description);
|
||||
if (kid == -ENOTSUP) {
|
||||
log_dbg(cd, "Kernel keyring features disabled.");
|
||||
return -ENOTSUP;
|
||||
} else if (kid < 0) {
|
||||
log_dbg(cd, "keyring_request_key_id failed with errno %d.", errno);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Reading content of kernel key (id %" PRIi32 ").", kid);
|
||||
|
||||
r = keyring_read_key(kid, key, key_size);
|
||||
if (r < 0)
|
||||
log_dbg(cd, "keyring_read_key failed with errno %d.", errno);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_keyring_get_key_by_name(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
char **key,
|
||||
size_t *key_size)
|
||||
{
|
||||
int r;
|
||||
key_serial_t kid;
|
||||
|
||||
if (!key_description || !key || !key_size)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Searching for key by name %s.", key_description);
|
||||
|
||||
kid = keyring_find_key_id_by_name(key_description);
|
||||
if (kid == -ENOTSUP) {
|
||||
log_dbg(cd, "Kernel keyring features disabled.");
|
||||
return -ENOTSUP;
|
||||
} else if (kid < 0) {
|
||||
log_dbg(cd, "keyring_find_key_id_by_name failed with errno %d.", errno);
|
||||
return -EINVAL;
|
||||
}
|
||||
else if (kid == 0) {
|
||||
log_dbg(cd, "keyring_find_key_id_by_name failed with errno %d.", ENOENT);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Reading content of kernel key (id %" PRIi32 ").", kid);
|
||||
|
||||
r = keyring_read_key(kid, key, key_size);
|
||||
if (r < 0)
|
||||
log_dbg(cd, "keyring_read_key failed with errno %d.", errno);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_key_in_keyring(struct crypt_device *cd)
|
||||
{
|
||||
@@ -7315,18 +7383,33 @@ void crypt_set_key_in_keyring(struct crypt_device *cd, unsigned key_in_keyring)
|
||||
/* internal only */
|
||||
void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype)
|
||||
{
|
||||
int r;
|
||||
key_serial_t kid;
|
||||
const char *type_name = key_type_name(ktype);
|
||||
|
||||
if (!key_description || !type_name)
|
||||
return;
|
||||
|
||||
log_dbg(cd, "Requesting keyring %s key for revoke and unlink.", type_name);
|
||||
log_dbg(cd, "Requesting kernel key %s (type %s) for unlink from thread keyring.", key_description, type_name);
|
||||
|
||||
r = keyring_revoke_and_unlink_key(ktype, key_description);
|
||||
if (r)
|
||||
log_dbg(cd, "keyring_revoke_and_unlink_key failed (error %d)", r);
|
||||
crypt_set_key_in_keyring(cd, 0);
|
||||
|
||||
kid = keyring_request_key_id(ktype, key_description);
|
||||
if (kid == -ENOTSUP) {
|
||||
log_dbg(cd, "Kernel keyring features disabled.");
|
||||
return;
|
||||
} else if (kid < 0) {
|
||||
log_dbg(cd, "keyring_request_key_id failed with errno %d.", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Unlinking volume key (id: %" PRIi32 ") from thread keyring.", kid);
|
||||
|
||||
if (!keyring_unlink_key_from_thread_keyring(kid))
|
||||
return;
|
||||
|
||||
log_dbg(cd, "keyring_unlink_key_from_thread_keyring failed with errno %d.", errno);
|
||||
log_err(cd, _("Failed to unlink volume key from thread keyring."));
|
||||
|
||||
}
|
||||
|
||||
int crypt_set_keyring_to_link(struct crypt_device *cd, const char *key_description,
|
||||
|
||||
@@ -270,6 +270,52 @@ int keyring_find_and_get_key_by_name(const char *key_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
key_serial_t keyring_request_key_id(key_type_t key_type,
|
||||
const char *key_description)
|
||||
{
|
||||
key_serial_t kid;
|
||||
|
||||
do {
|
||||
kid = request_key(key_type_name(key_type), key_description, NULL, 0);
|
||||
} while (kid < 0 && errno == EINTR);
|
||||
|
||||
return kid;
|
||||
}
|
||||
|
||||
int keyring_read_key(key_serial_t kid,
|
||||
char **key,
|
||||
size_t *key_size)
|
||||
{
|
||||
long r;
|
||||
char *buf = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
assert(key);
|
||||
assert(key_size);
|
||||
|
||||
/* just get payload size */
|
||||
r = keyctl_read(kid, NULL, 0);
|
||||
if (r > 0) {
|
||||
len = r;
|
||||
buf = crypt_safe_alloc(len);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* retrieve actual payload data */
|
||||
r = keyctl_read(kid, buf, len);
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
crypt_safe_free(buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*key = buf;
|
||||
*key_size = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyring_get_user_key(const char *key_desc,
|
||||
char **key,
|
||||
size_t *key_size)
|
||||
@@ -316,6 +362,11 @@ int keyring_unlink_key_from_keyring(key_serial_t kid, key_serial_t keyring_id)
|
||||
return keyctl_unlink(kid, keyring_id) < 0 ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
int keyring_unlink_key_from_thread_keyring(key_serial_t kid)
|
||||
{
|
||||
return keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING) < 0 ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static int keyring_revoke_and_unlink_key_type(const char *type_name, const char *key_desc)
|
||||
{
|
||||
key_serial_t kid;
|
||||
@@ -489,6 +540,19 @@ int keyring_find_and_get_key_by_name(const char *key_name,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
key_serial_t keyring_request_key_id(key_type_t key_type,
|
||||
const char *key_description)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int keyring_read_key(key_serial_t kid,
|
||||
char **key,
|
||||
size_t *key_size)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int keyring_read_by_id(const char *key_desc, char **passphrase, size_t *passphrase_len)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
@@ -537,4 +601,9 @@ int keyring_unlink_key_from_keyring(key_serial_t kid, key_serial_t keyring_id)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int keyring_unlink_key_from_thread_keyring(key_serial_t kid)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,13 @@ int32_t keyring_find_keyring_id_by_name(const char *keyring_name);
|
||||
|
||||
int keyring_check(void);
|
||||
|
||||
key_serial_t keyring_request_key_id(key_type_t key_type,
|
||||
const char *key_description);
|
||||
|
||||
int keyring_read_key(key_serial_t kid,
|
||||
char **key,
|
||||
size_t *key_size);
|
||||
|
||||
int keyring_get_user_key(const char *key_desc,
|
||||
char **key,
|
||||
size_t *key_size);
|
||||
@@ -70,5 +77,6 @@ int keyring_revoke_and_unlink_key(key_type_t ktype, const char *key_desc);
|
||||
key_serial_t keyring_add_key_to_custom_keyring(key_type_t ktype, const char *key_desc, const void *key,
|
||||
size_t key_size, key_serial_t keyring_to_link);
|
||||
int keyring_unlink_key_from_keyring(key_serial_t kid, key_serial_t keyring_id);
|
||||
int keyring_unlink_key_from_thread_keyring(key_serial_t kid);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user