Skip to content

Commit cf29d51

Browse files
onikombroz
authored andcommitted
Refactor activation by volume key(s) in helper routine.
1 parent 8fcd8a7 commit cf29d51

3 files changed

Lines changed: 111 additions & 47 deletions

File tree

src/cryptsetup.c

Lines changed: 26 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,11 +1724,10 @@ static int action_open_luks(void)
17241724
struct crypt_active_device cad;
17251725
struct crypt_device *cd = NULL;
17261726
const char *data_device, *header_device, *activated_name;
1727-
char *key = NULL, *vk_description_activation1 = NULL, *vk_description_activation2 = NULL;
17281727
uint32_t activate_flags = 0;
1729-
int r, keysize, tries;
1728+
int r, tries, keysize = 0;
17301729
struct stat st;
1731-
struct crypt_keyslot_context *kc = NULL, *kc1 = NULL, *kc2 = NULL;
1730+
struct crypt_keyslot_context *kc1 = NULL, *kc2 = NULL;
17321731

17331732
if (ARG_SET(OPT_REFRESH_ID)) {
17341733
activated_name = action_argc > 1 ? action_argv[1] : action_argv[0];
@@ -1785,48 +1784,31 @@ static int action_open_luks(void)
17851784
goto out;
17861785
}
17871786

1788-
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID)) {
1789-
keysize = crypt_get_volume_key_size(cd);
1790-
if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
1791-
log_err(_("Cannot determine volume key size for LUKS without keyslots, please use --key-size option."));
1792-
r = -EINVAL;
1793-
goto out;
1794-
} else if (!keysize)
1795-
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
1787+
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID) || ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
1788+
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID)) {
1789+
keysize = crypt_get_volume_key_size(cd);
1790+
if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
1791+
log_err(_("Cannot determine volume key size for LUKS without keyslots, please use --key-size option."));
1792+
r = -EINVAL;
1793+
goto out;
1794+
} else if (!keysize)
1795+
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
1796+
}
17961797

1797-
r = tools_read_vk(ARG_STR(OPT_VOLUME_KEY_FILE_ID), &key, keysize);
1798+
r = luks_init_keyslot_contexts_by_volume_keys(cd, ARG_STR(OPT_VOLUME_KEY_FILE_ID),
1799+
NULL /* unused */,
1800+
keysize,
1801+
0 /* unused */,
1802+
vks_in_keyring[0],
1803+
vks_in_keyring[1],
1804+
&kc1, &kc2);
17981805
if (r < 0)
17991806
goto out;
1800-
r = crypt_activate_by_volume_key(cd, activated_name,
1801-
key, keysize, activate_flags);
1802-
} else if (ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
1803-
if (vks_in_keyring_count == 1) {
1804-
r = tools_parse_vk_description(vks_in_keyring[0], &vk_description_activation1);
1805-
if (r < 0)
1806-
goto out;
1807-
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1);
1808-
if (r)
1809-
goto out;
1810-
r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT, kc1, CRYPT_ANY_SLOT, NULL, activate_flags);
1811-
} else if (vks_in_keyring_count == 2) {
1812-
r = tools_parse_vk_description(vks_in_keyring[0], &vk_description_activation1);
1813-
if (r < 0)
1814-
goto out;
1815-
r = tools_parse_vk_description(vks_in_keyring[1], &vk_description_activation2);
1816-
if (r < 0)
1817-
goto out;
1818-
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation1, &kc1);
1819-
if (r)
1820-
goto out;
1821-
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description_activation2, &kc2);
1822-
if (r)
1823-
goto out;
1824-
r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT, kc1, CRYPT_ANY_SLOT, kc2, activate_flags);
1825-
}
1807+
1808+
r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT,
1809+
kc1, CRYPT_ANY_SLOT, kc2, activate_flags);
18261810
if (r == -EPERM)
18271811
log_err(_("Volume key does not match the volume."));
1828-
if (r)
1829-
goto out;
18301812
} else {
18311813
r = luks_try_token_unlock(cd, ARG_INT32(OPT_KEY_SLOT_ID),
18321814
ARG_INT32(OPT_TOKEN_ID_ID), activated_name,
@@ -1840,14 +1822,14 @@ static int action_open_luks(void)
18401822

18411823
tries = set_tries_tty(true);
18421824
do {
1843-
r = luks_init_keyslot_context(cd, NULL, verify_passphrase(0), false, &kc);
1825+
crypt_keyslot_context_free(kc1);
1826+
kc1 = NULL;
1827+
r = luks_init_keyslot_context(cd, NULL, verify_passphrase(0), false, &kc1);
18441828
if (r < 0)
18451829
goto out;
18461830

18471831
r = crypt_activate_by_keyslot_context(cd, activated_name, ARG_INT32(OPT_KEY_SLOT_ID),
1848-
kc, CRYPT_ANY_SLOT, kc, activate_flags);
1849-
crypt_keyslot_context_free(kc);
1850-
kc = NULL;
1832+
kc1, CRYPT_ANY_SLOT, kc1, activate_flags);
18511833

18521834
tools_keyslot_msg(r, UNLOCKED);
18531835
tools_passphrase_msg(r);
@@ -1868,10 +1850,7 @@ static int action_open_luks(void)
18681850

18691851
crypt_keyslot_context_free(kc1);
18701852
crypt_keyslot_context_free(kc2);
1871-
crypt_safe_free(key);
18721853
crypt_free(cd);
1873-
free(vk_description_activation1);
1874-
free(vk_description_activation2);
18751854

18761855
return r;
18771856
}

src/utils_luks.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,78 @@ int luks_try_token_unlock(struct crypt_device *cd,
376376

377377
return r;
378378
}
379+
380+
/* Initiates keyslot context(s) based on non-interactive input only */
381+
int luks_init_keyslot_contexts_by_volume_keys(struct crypt_device *cd,
382+
const char *vk_file1,
383+
const char *vk_file2,
384+
int keysize1_bytes,
385+
int keysize2_bytes,
386+
const char *vk_in_keyring1,
387+
const char *vk_in_keyring2,
388+
struct crypt_keyslot_context **r_kc1,
389+
struct crypt_keyslot_context **r_kc2)
390+
{
391+
int r = -EINVAL;
392+
char *vk_description = NULL, *key = NULL;
393+
struct crypt_keyslot_context *kc1 = NULL, *kc2 = NULL;
394+
395+
assert(cd);
396+
assert(r_kc1);
397+
assert(r_kc2);
398+
399+
if (vk_file1 && keysize1_bytes > 0) {
400+
r = tools_read_vk(vk_file1, &key, keysize1_bytes);
401+
if (r < 0)
402+
return r;
403+
404+
r = crypt_keyslot_context_init_by_volume_key(cd, key, keysize1_bytes, &kc1);
405+
if (r < 0)
406+
goto out;
407+
}
408+
409+
/* volume key in file takes precedence */
410+
if (vk_in_keyring1 && !kc1) {
411+
r = tools_parse_vk_description(vk_in_keyring1, &vk_description);
412+
if (r < 0)
413+
goto out;
414+
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description, &kc1);
415+
if (r < 0)
416+
goto out;
417+
}
418+
419+
if (vk_file2 && keysize2_bytes > 0) {
420+
crypt_safe_free(key);
421+
key = NULL;
422+
r = tools_read_vk(vk_file2, &key, keysize2_bytes);
423+
if (r < 0)
424+
goto out;
425+
426+
r = crypt_keyslot_context_init_by_volume_key(cd, key, keysize2_bytes, &kc2);
427+
if (r < 0)
428+
goto out;
429+
}
430+
431+
/* volume key in file takes precedence */
432+
if (vk_in_keyring2 && !kc2) {
433+
free(vk_description);
434+
vk_description = NULL;
435+
r = tools_parse_vk_description(vk_in_keyring2, &vk_description);
436+
if (r < 0)
437+
goto out;
438+
r = crypt_keyslot_context_init_by_vk_in_keyring(cd, vk_description, &kc2);
439+
}
440+
out:
441+
crypt_safe_free(key);
442+
free(vk_description);
443+
444+
if (r) {
445+
crypt_keyslot_context_free(kc1);
446+
crypt_keyslot_context_free(kc2);
447+
} else {
448+
*r_kc1 = kc1;
449+
*r_kc2 = kc2;
450+
}
451+
452+
return r;
453+
}

src/utils_luks.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,14 @@ int luks_try_token_unlock(struct crypt_device *cd,
5454
bool retry_with_pin,
5555
struct crypt_keyslot_context **r_kc);
5656

57+
int luks_init_keyslot_contexts_by_volume_keys(struct crypt_device *cd,
58+
const char *vk_file1,
59+
const char *vk_file2,
60+
int keysize1_bytes,
61+
int keysize2_bytes,
62+
const char *vk_in_keyring1,
63+
const char *vk_in_keyring2,
64+
struct crypt_keyslot_context **r_kc1,
65+
struct crypt_keyslot_context **r_kc2);
66+
5767
#endif /* UTILS_LUKS_H */

0 commit comments

Comments
 (0)