mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-17 13:50:06 +01:00
Add luksChangeKey command.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@450 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
2011-04-11 Milan Broz <mbroz@redhat.com>
|
2011-04-11 Milan Broz <mbroz@redhat.com>
|
||||||
* Add loop manipulation code and support mapping of images in file.
|
* Add loop manipulation code and support mapping of images in file.
|
||||||
* Add backing device loop info into status message.
|
* Add backing device loop info into status message.
|
||||||
|
* Add luksChangeKey command.
|
||||||
|
|
||||||
2011-04-05 Milan Broz <mbroz@redhat.com>
|
2011-04-05 Milan Broz <mbroz@redhat.com>
|
||||||
* Add exception to COPYING for binary distribution linked with OpenSSL library.
|
* Add exception to COPYING for binary distribution linked with OpenSSL library.
|
||||||
|
|||||||
@@ -46,6 +46,21 @@ static inline int round_up_modulo(int x, int m) {
|
|||||||
return div_round_up(x, m) * m;
|
return div_round_up(x, m) * m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *dbg_slot_state(crypt_keyslot_info ki)
|
||||||
|
{
|
||||||
|
switch(ki) {
|
||||||
|
case CRYPT_SLOT_INACTIVE:
|
||||||
|
return "INACTIVE";
|
||||||
|
case CRYPT_SLOT_ACTIVE:
|
||||||
|
return "ACTIVE";
|
||||||
|
case CRYPT_SLOT_ACTIVE_LAST:
|
||||||
|
return "ACTIVE_LAST";
|
||||||
|
case CRYPT_SLOT_INVALID:
|
||||||
|
default:
|
||||||
|
return "INVALID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int LUKS_hdr_backup(
|
int LUKS_hdr_backup(
|
||||||
const char *backup_file,
|
const char *backup_file,
|
||||||
const char *device,
|
const char *device,
|
||||||
@@ -629,7 +644,8 @@ static int LUKS_open_key(const char *device,
|
|||||||
size_t AFEKSize;
|
size_t AFEKSize;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
log_dbg("Trying to open key slot %d [%d].", keyIndex, (int)ki);
|
log_dbg("Trying to open key slot %d [%s].", keyIndex,
|
||||||
|
dbg_slot_state(ki));
|
||||||
|
|
||||||
if (ki < CRYPT_SLOT_ACTIVE)
|
if (ki < CRYPT_SLOT_ACTIVE)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|||||||
@@ -82,6 +82,20 @@ The key file with the new material is supplied as a positional argument.
|
|||||||
.IP
|
.IP
|
||||||
remove supplied key or key file from LUKS device
|
remove supplied key or key file from LUKS device
|
||||||
.PP
|
.PP
|
||||||
|
\fIluksChangeKey\fR <device> [<new key file>]
|
||||||
|
.IP
|
||||||
|
change existing key file or passphrase. An existing passphrase or key file (via \-\-key-file) must be supplied.
|
||||||
|
The key file with the new material is supplied as a positional argument.
|
||||||
|
|
||||||
|
If no key slot is specified (and there is still free key slot on device) new slot is allocated before the old is purged.
|
||||||
|
|
||||||
|
If \fB\-\-key\-slot\fR option is specified (or there is no free slot) command will overwrite existing slot.
|
||||||
|
|
||||||
|
\fBWARNING:\fR Be sure you have another slot active or header backup when using explicit key slot (so you can
|
||||||
|
unlock the device even after possible media failure during slot swap).
|
||||||
|
|
||||||
|
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-new-keyfile-size, \-\-key-slot].
|
||||||
|
.PP
|
||||||
\fIluksKillSlot\fR <device> <key slot number>
|
\fIluksKillSlot\fR <device> <key slot number>
|
||||||
.IP
|
.IP
|
||||||
wipe key with number <key slot> from LUKS device. A remaining passphrase or
|
wipe key with number <key slot> from LUKS device. A remaining passphrase or
|
||||||
@@ -258,6 +272,7 @@ set up a read-only mapping.
|
|||||||
.TP
|
.TP
|
||||||
.B "\-\-iter-time, \-i"
|
.B "\-\-iter-time, \-i"
|
||||||
The number of milliseconds to spend with PBKDF2 password processing. This option is only relevant to the LUKS operations as \fIluksFormat\fR or \fIluksAddKey\fR.
|
The number of milliseconds to spend with PBKDF2 password processing. This option is only relevant to the LUKS operations as \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||||
|
Note that 0 means default.
|
||||||
.TP
|
.TP
|
||||||
.B "\-\-batch-mode, \-q"
|
.B "\-\-batch-mode, \-q"
|
||||||
Do not ask for confirmation. Use with care! This option is only relevant for \fIluksFormat\fR, \fIluksAddKey\fR, \fIluksRemoveKey\fR or \fIluksKillSlot\fR.
|
Do not ask for confirmation. Use with care! This option is only relevant for \fIluksFormat\fR, \fIluksAddKey\fR, \fIluksRemoveKey\fR or \fIluksKillSlot\fR.
|
||||||
@@ -341,7 +356,7 @@ Copyright \(co 2004 Christophe Saout
|
|||||||
.br
|
.br
|
||||||
Copyright \(co 2004-2006 Clemens Fruhwirth
|
Copyright \(co 2004-2006 Clemens Fruhwirth
|
||||||
.br
|
.br
|
||||||
Copyright \(co 2009-2010 Red Hat, Inc.
|
Copyright \(co 2009-2011 Red Hat, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ static int action_luksOpen(int arg);
|
|||||||
static int action_luksAddKey(int arg);
|
static int action_luksAddKey(int arg);
|
||||||
static int action_luksKillSlot(int arg);
|
static int action_luksKillSlot(int arg);
|
||||||
static int action_luksRemoveKey(int arg);
|
static int action_luksRemoveKey(int arg);
|
||||||
|
static int action_luksChangeKey(int arg);
|
||||||
static int action_isLuks(int arg);
|
static int action_isLuks(int arg);
|
||||||
static int action_luksUUID(int arg);
|
static int action_luksUUID(int arg);
|
||||||
static int action_luksDump(int arg);
|
static int action_luksDump(int arg);
|
||||||
@@ -81,6 +82,7 @@ static struct action_type {
|
|||||||
{ "luksOpen", action_luksOpen, 0, 2, 1, N_("<device> <name> "), N_("open LUKS device as mapping <name>") },
|
{ "luksOpen", action_luksOpen, 0, 2, 1, N_("<device> <name> "), N_("open LUKS device as mapping <name>") },
|
||||||
{ "luksAddKey", action_luksAddKey, 0, 1, 1, N_("<device> [<new key file>]"), N_("add key to LUKS device") },
|
{ "luksAddKey", action_luksAddKey, 0, 1, 1, N_("<device> [<new key file>]"), N_("add key to LUKS device") },
|
||||||
{ "luksRemoveKey",action_luksRemoveKey, 0, 1, 1, N_("<device> [<key file>]"), N_("removes supplied key or key file from LUKS device") },
|
{ "luksRemoveKey",action_luksRemoveKey, 0, 1, 1, N_("<device> [<key file>]"), N_("removes supplied key or key file from LUKS device") },
|
||||||
|
{ "luksChangeKey",action_luksChangeKey, 0, 1, 1, N_("<device> [<key file>]"), N_("changes supplied key or key file of LUKS device") },
|
||||||
{ "luksKillSlot", action_luksKillSlot, 0, 2, 1, N_("<device> <key slot>"), N_("wipes key with number <key slot> from LUKS device") },
|
{ "luksKillSlot", action_luksKillSlot, 0, 2, 1, N_("<device> <key slot>"), N_("wipes key with number <key slot> from LUKS device") },
|
||||||
{ "luksUUID", action_luksUUID, 0, 1, 0, N_("<device>"), N_("print UUID of LUKS device") },
|
{ "luksUUID", action_luksUUID, 0, 1, 0, N_("<device>"), N_("print UUID of LUKS device") },
|
||||||
{ "isLuks", action_isLuks, 0, 1, 0, N_("<device>"), N_("tests <device> for LUKS partition header") },
|
{ "isLuks", action_isLuks, 0, 1, 0, N_("<device>"), N_("tests <device> for LUKS partition header") },
|
||||||
@@ -671,6 +673,100 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _slots_full(struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < crypt_keyslot_max(crypt_get_type(cd)); i++)
|
||||||
|
if (crypt_keyslot_status(cd, i) == CRYPT_SLOT_INACTIVE)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int action_luksChangeKey(int arg)
|
||||||
|
{
|
||||||
|
const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
|
||||||
|
struct crypt_device *cd = NULL;
|
||||||
|
char *vk = NULL, *password = NULL;
|
||||||
|
unsigned int passwordLen = 0;
|
||||||
|
size_t vk_size;
|
||||||
|
int new_key_slot, old_key_slot, r;
|
||||||
|
|
||||||
|
if ((r = crypt_init(&cd, action_argv[0])))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
r = crypt_get_key(_("Enter LUKS passphrase to be changed: "),
|
||||||
|
&password, &passwordLen,
|
||||||
|
opt_keyfile_size, opt_key_file, opt_timeout,
|
||||||
|
opt_batch_mode ? 0 : opt_verify_passphrase, cd);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
vk_size = crypt_get_volume_key_size(cd);
|
||||||
|
vk = crypt_safe_alloc(vk_size);
|
||||||
|
if (!vk) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = crypt_volume_key_get(cd, opt_key_slot, vk, &vk_size,
|
||||||
|
password, passwordLen);
|
||||||
|
if (r < 0) {
|
||||||
|
if (opt_key_slot != CRYPT_ANY_SLOT)
|
||||||
|
log_err(_("No key available with this passphrase.\n"));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_key_slot != CRYPT_ANY_SLOT || _slots_full(cd)) {
|
||||||
|
log_dbg("Key slot %d is going to be overwritten (%s).",
|
||||||
|
r, opt_key_slot != CRYPT_ANY_SLOT ?
|
||||||
|
"explicit key slot specified" : "no free key slot");
|
||||||
|
old_key_slot = r;
|
||||||
|
new_key_slot = r;
|
||||||
|
} else {
|
||||||
|
log_dbg("Allocating new key slot.");
|
||||||
|
old_key_slot = r;
|
||||||
|
new_key_slot = CRYPT_ANY_SLOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypt_safe_free(password);
|
||||||
|
password = NULL;
|
||||||
|
passwordLen = 0;
|
||||||
|
r = crypt_get_key(_("Enter new LUKS passphrase: "),
|
||||||
|
&password, &passwordLen,
|
||||||
|
opt_new_keyfile_size, opt_new_key_file,
|
||||||
|
opt_timeout, opt_batch_mode ? 0 : 1, cd);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (new_key_slot == old_key_slot) {
|
||||||
|
(void)crypt_keyslot_destroy(cd, old_key_slot);
|
||||||
|
r = crypt_keyslot_add_by_volume_key(cd, new_key_slot,
|
||||||
|
vk, vk_size,
|
||||||
|
password, passwordLen);
|
||||||
|
if (r >= 0)
|
||||||
|
log_verbose(_("Key slot %d changed.\n"), r);
|
||||||
|
} else {
|
||||||
|
r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT,
|
||||||
|
vk, vk_size,
|
||||||
|
password, passwordLen);
|
||||||
|
if (r >= 0) {
|
||||||
|
log_verbose(_("Replaced with key slot %d.\n"), r);
|
||||||
|
r = crypt_keyslot_destroy(cd, old_key_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r < 0)
|
||||||
|
log_err(_("Failed to swap new key slot.\n"));
|
||||||
|
out:
|
||||||
|
crypt_safe_free(vk);
|
||||||
|
crypt_safe_free(password);
|
||||||
|
crypt_free(cd);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_isLuks(int arg)
|
static int action_isLuks(int arg)
|
||||||
{
|
{
|
||||||
struct crypt_device *cd = NULL;
|
struct crypt_device *cd = NULL;
|
||||||
|
|||||||
@@ -300,5 +300,30 @@ dmsetup resume $DEV_NAME || fail
|
|||||||
$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
|
$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
|
||||||
dmsetup remove $DEV_NAME || fail
|
dmsetup remove $DEV_NAME || fail
|
||||||
|
|
||||||
|
prepare "[23] ChangeKey passphrase and keyfile" wipe
|
||||||
|
# [0]$KEY1 [1]key0
|
||||||
|
$CRYPTSETUP -q luksFormat $LOOPDEV $KEY1 --key-slot 0 || fail
|
||||||
|
echo "key0" | $CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 --key-slot 1 || fail
|
||||||
|
# keyfile [0] / keyfile [0]
|
||||||
|
$CRYPTSETUP luksChangeKey $LOOPDEV -d $KEY1 $KEY2 --key-slot 0 || fail
|
||||||
|
# passphrase [1] / passphrase [1]
|
||||||
|
echo -e "key0\nkey1\n" | $CRYPTSETUP luksChangeKey $LOOPDEV --key-slot 1 || fail
|
||||||
|
# keyfile [0] / keyfile [new]
|
||||||
|
$CRYPTSETUP luksChangeKey $LOOPDEV -d $KEY2 $KEY1 || fail
|
||||||
|
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 0: DISABLED" || fail
|
||||||
|
# passphrase [1] / passphrase [new]
|
||||||
|
echo -e "key1\nkey0\n" | $CRYPTSETUP luksChangeKey $LOOPDEV || fail
|
||||||
|
$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail
|
||||||
|
# use all slots
|
||||||
|
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 -i 1 || fail
|
||||||
|
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 -i 1 || fail
|
||||||
|
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 -i 1 || fail
|
||||||
|
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 -i 1 || fail
|
||||||
|
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 -i 1 || fail
|
||||||
|
$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 -i 1 || fail
|
||||||
|
# still allows replace
|
||||||
|
$CRYPTSETUP luksChangeKey $LOOPDEV -d $KEY1 $KEY2 || fail
|
||||||
|
$CRYPTSETUP luksChangeKey $LOOPDEV -d $KEY1 $KEY2 2>/dev/null && fail
|
||||||
|
|
||||||
remove_mapping
|
remove_mapping
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user