Commit fb6b4739 authored by Milan Broz's avatar Milan Broz

Clean up keyring handling.

Move all keyring functions to one place and separate LUKS2 specific
code to generic handling.

Also fix possible mismatch if volume key is in keyring but it is not native
LUKS2 device (libarary cannot process such a device properly).
parent 32700cc5
...@@ -191,6 +191,9 @@ int crypt_get_integrity_tag_size(struct crypt_device *cd); ...@@ -191,6 +191,9 @@ int crypt_get_integrity_tag_size(struct crypt_device *cd);
int crypt_key_in_keyring(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); 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_use_keyring_for_vk(const struct crypt_device *cd);
void crypt_drop_keyring_key(struct crypt_device *cd, const char *key_description);
static inline uint64_t version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release) static inline uint64_t version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release)
{ {
......
...@@ -352,11 +352,10 @@ int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr ...@@ -352,11 +352,10 @@ int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet); int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet);
int crypt_use_keyring_for_vk(const struct crypt_device *cd); int LUKS2_key_description_by_segment(struct crypt_device *cd,
int crypt_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd, struct volume_key *vk, int keyslot); struct luks2_hdr *hdr, struct volume_key *vk, int segment);
void crypt_drop_keyring_key(struct crypt_device *cd, const char *key_description); int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd,
int crypt_get_passphrase_from_keyring(const char *key_description, struct luks2_hdr *hdr, struct volume_key *vk, int keyslot);
char **passphrase, size_t *passphrase_len);
struct luks_phdr; struct luks_phdr;
int LUKS2_luks1_to_luks2(struct crypt_device *cd, int LUKS2_luks1_to_luks2(struct crypt_device *cd,
......
...@@ -341,3 +341,58 @@ void LUKS2_digests_erase_unused(struct crypt_device *cd, ...@@ -341,3 +341,58 @@ void LUKS2_digests_erase_unused(struct crypt_device *cd,
} }
} }
} }
/* Key description helpers */
static char *get_key_description_by_digest(struct crypt_device *cd, int digest)
{
char *desc, digest_str[3];
int r;
size_t len;
if (!crypt_get_uuid(cd))
return NULL;
r = snprintf(digest_str, sizeof(digest_str), "d%u", digest);
if (r < 0 || (size_t)r >= sizeof(digest_str))
return NULL;
/* "cryptsetup:<uuid>-<digest_str>" + \0 */
len = strlen(crypt_get_uuid(cd)) + strlen(digest_str) + 13;
desc = malloc(len);
if (!desc)
return NULL;
r = snprintf(desc, len, "%s:%s-%s", "cryptsetup", crypt_get_uuid(cd), digest_str);
if (r < 0 || (size_t)r >= len) {
free(desc);
return NULL;
}
return desc;
}
int LUKS2_key_description_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr, struct volume_key *vk, int segment)
{
char *desc = get_key_description_by_digest(cd, LUKS2_digest_by_segment(cd, hdr, segment));
int r;
r = crypt_volume_key_set_description(vk, desc);
free(desc);
return r;
}
int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd,
struct luks2_hdr *hdr, struct volume_key *vk, int keyslot)
{
char *desc = get_key_description_by_digest(cd, LUKS2_digest_by_keyslot(cd, hdr, keyslot));
int r;
r = crypt_volume_key_set_description(vk, desc);
if (!r)
r = crypt_volume_key_load_in_keyring(cd, vk);
free(desc);
return r;
}
...@@ -404,7 +404,7 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd, ...@@ -404,7 +404,7 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
keyslot = r; keyslot = r;
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd))
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot); r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot);
if (r >= 0 && name) if (r >= 0 && name)
r = LUKS2_activate(cd, name, vk, flags); r = LUKS2_activate(cd, name, vk, flags);
...@@ -448,7 +448,7 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd, ...@@ -448,7 +448,7 @@ int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
keyslot = r; keyslot = r;
if (r >= 0 && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) if (r >= 0 && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd))
r = crypt_volume_key_load_in_keyring_by_keyslot(cd, vk, keyslot); r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot);
if (r >= 0 && name) if (r >= 0 && name)
r = LUKS2_activate(cd, name, vk, flags); r = LUKS2_activate(cd, name, vk, flags);
......
...@@ -31,6 +31,7 @@ static int keyring_open(struct crypt_device *cd, ...@@ -31,6 +31,7 @@ static int keyring_open(struct crypt_device *cd,
{ {
json_object *jobj_token, *jobj_key; json_object *jobj_token, *jobj_key;
struct luks2_hdr *hdr; struct luks2_hdr *hdr;
int r;
if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2))) if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
return -EINVAL; return -EINVAL;
...@@ -41,8 +42,14 @@ static int keyring_open(struct crypt_device *cd, ...@@ -41,8 +42,14 @@ static int keyring_open(struct crypt_device *cd,
json_object_object_get_ex(jobj_token, "key_description", &jobj_key); json_object_object_get_ex(jobj_token, "key_description", &jobj_key);
if (crypt_get_passphrase_from_keyring(json_object_get_string(jobj_key), buffer, buffer_len)) r = keyring_get_passphrase(json_object_get_string(jobj_key), buffer, buffer_len);
if (r == -ENOTSUP) {
log_dbg("Kernel keyring features disabled.");
return -EINVAL; return -EINVAL;
} else if (r < 0) {
log_dbg("keyring_get_passphrase failed (error %d)", r);
return -EINVAL;
}
return 0; return 0;
} }
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment