tomb

the crypto undertaker
git clone git://parazyd.org/tomb.git
Log | Files | Refs | README | LICENSE

commit 342c121fa2e77e98cf937aa76d3a4ef331e9f8f1
parent 84d438569603eb8448a3965bbe1fb7b54168a1fc
Author: Jaromil <jaromil@dyne.org>
Date:   Fri, 22 Mar 2013 22:22:55 +0100

completed new create procedure

Diffstat:
Msrc/tomb | 187++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 171 insertions(+), 16 deletions(-)

diff --git a/src/tomb b/src/tomb @@ -799,7 +799,7 @@ create_tomb() { die "operation aborted." 0 fi - cryptsetup --key-file ${keytmp}/tomb.tmp --cipher ${create_cipher}:sha256 luksOpen ${nstloop} tomb.tmp + cryptsetup --key-file ${keytmp}/tomb.tmp --cipher ${create_cipher} luksOpen ${nstloop} tomb.tmp ${=WIPE} ${keytmp}/tomb.tmp umount ${keytmp} rm -r ${keytmp} @@ -819,7 +819,7 @@ create_tomb() { cryptsetup luksClose tomb.tmp losetup -d ${nstloop} - _message "done creating $tombname encrypted storage (using Luks dm-crypt ${create_cipher}:sha256)" + _message "done creating $tombname encrypted storage (using Luks dm-crypt ${create_cipher})" _success "Your tomb is ready in ${tombdir}/${tombfile} and secured with key ${tombkey}" } @@ -844,13 +844,6 @@ forge_key() { # if swap is on, we remind the user about possible data leaks to disk if ! option_is_set -f && ! option_is_set --ignore-swap; then check_swap; fi - # the encryption cipher for a tomb can be set at creation using -o - if ! option_is_set -o; then - create_cipher="`option_value -o`" - else - create_cipher=aes-cbc-essiv:sha256 - fi - # create the keyfile in tmpfs so that we leave less traces in RAM keytmp=`safe_dir tomb` @@ -978,6 +971,169 @@ dig_tomb() { _message "tomb lock ${tombname}.tomb ${tombname}.tomb.key" } +# this function locks a tomb with a key file +# in fact LUKS formatting the loopback volume +# it take arguments as the LUKS cipher to be used +lock_tomb_with_key() { + _message "Commanded to lock tomb ${tombfile}" + if ! [ $1 ]; then + _warning "no tomb specified for locking" + return 1 + fi + + tombfile=`basename $1` + tombdir=`dirname $1` + # make sure the file has a .tomb extension + tombname=${tombfile%%\.*} + tombfile=${tombname}.tomb + + if ! [ -e ${tombdir}/${tombfile} ]; then + die "There is no tomb here. You have to it dig first." + return 1 + fi + + xxx "tomb found: ${tombdir}/${tombfile}" + + nstloop=`losetup -f` # get the number for next loopback device + losetup -f ${tombdir}/${tombfile} # allocates the next loopback for our file + + xxx "loop mounted on ${nstloop}" + + _message "checking if the tomb is empty (we never step on somebody else's bones)" + cryptsetup isLuks ${nstloop} + if [ $? = 0 ]; then + # is it a LUKS encrypted nest? then bail out and avoid reformatting it + _warning "The tomb was already locked with another key" + losetup -d ${nstloop} + die "Operation aborted. I cannot lock an already locked tomb. Go dig a new one." + else + _message "fine, this tomb seems empty." + fi + + # check if the key is set manually then use the one existing + if option_is_set -k ; then + if [[ "`option_value -k`" == "-" ]]; then + # take key from stdin + local tombkeydir + tombkeydir=`safe_dir` + cat > ${tombkeydir}/stdin.tmp + tombkey=${tombkeydir}/stdin.tmp + else + # take key from a file + tombkey=`option_value -k` + fi + else + # guess key as lying besides the tomb + tombkey=${tombdir}/${tombname}.tomb.key + fi + + if [ -r "${tombkey}" ]; then + _message "We'll use this key to lock the tomb:" + _message " `ls -lh ${tombkey}`" + else + losetup -d ${nstloop} + die "No key found. Use the option -k to specify a key file." + fi + + # this does a check on the file header, virtuosism by hellekin + # [[ `file =(awk '/^-+BEGIN/,0' $1) -bi` =~ application/pgp ]] + if ! is_valid_key ${tombkey}; then + _warning "The key seems invalid, the application/pgp header is missing" + losetup -d ${nstloop} + die "Operation aborted." + fi + + # the encryption cipher for a tomb can be set at creation using -o + if option_is_set -o; then + cipher="`option_value -o`" + else + cipher="aes-cbc-essiv:sha256" + fi + _message "locking using cipher: $cipher" + + keyname=`basename $tombkey | cut -d. -f1` + _message "a password is required to use key ${keyname}" + if option_is_set --tomb-pwd; then + tombpass=`option_value --tomb-pwd` + else + + for c in 1 2 3; do + if [ $c = 1 ]; then + tombpass=`exec_as_user ${TOMBEXEC} askpass "Insert password to use key: $keyname"` + else + tombpass=`exec_as_user ${TOMBEXEC} askpass "Insert password to use key: $keyname (retry $c)"` + fi + if [[ $? != 0 ]]; then + losetup -d ${nstloop} + die "User aborted" + fi + + gpg --batch --passphrase-fd 0 --no-tty --no-options \ + -d "${tombkey}" 1> /dev/null 2>/dev/null <<< ${tombpass} + if [[ $? = 0 ]]; then + passok=1 + _message "Password OK." + break; + fi + done + fi + if [[ $passok != 1 ]]; then + _warning "Password incorrect" + losetup -d $nstloop + die "Operation aborted." + fi + + _success "Locking ${tombfile} with ${tombkey}" + + echo + get_lukskey "${tombpass}" ${tombkey} + echo + xxx "cryptsetup --key-file - --batch-mode --cipher ${cipher} --key-size 256 luksFormat ${nstloop}" + + _message "formatting Luks mapped device" + get_lukskey "${tombpass}" ${tombkey} | \ + cryptsetup --key-file - --batch-mode \ + --cipher ${cipher} --key-size 256 \ + luksFormat ${nstloop} + if ! [ $? = 0 ]; then + _warning "cryptsetup luksFormat returned an error" + unset tombpass + losetup -d $nstloop + die "Operation aborted." + fi + + + + get_lukskey "${tombpass}" ${tombkey} | \ + cryptsetup --key-file - \ + --cipher ${cipher} luksOpen ${nstloop} tomb.tmp + if ! [ $? = 0 ]; then + _warning "cryptsetup luksOpen returned an error" + unset tombpass + losetup -d $nstloop + die "Operation aborted." + fi + + unset tombpass + + _message "formatting your Tomb with Ext3/Ext4 filesystem" + ${=MKFS} ${tombname} /dev/mapper/tomb.tmp + + if [ $? != 0 ]; then + _warning "Tomb format returned an error" + _warning "your tomb ${tombfile} may be corrupted." + fi + + sync + + cryptsetup luksClose tomb.tmp + losetup -d ${nstloop} + + + _message "done locking $tombname using Luks dm-crypt ${create_cipher}" + _success "Your tomb is ready in ${tombdir}/${tombfile} and secured with key ${tombkey}" + +} #internal use #$1 is the keyfile we are checking @@ -1229,12 +1385,6 @@ mount_tomb() { rmdir $tombkeydir fi - # if key was from stdin delete temp file and dir - if [ $tombkeydir ]; then - ${WIPE[@]} ${tombkey} - rmdir $tombkeydir - fi - if [ -r /dev/mapper/${mapper} ]; then break; # password was correct fi @@ -1938,6 +2088,7 @@ main() { subcommands_opts[forge]="f -ignore-swap -kdf: -use-urandom U: -uid=U G: -gid=G" subcommands_opts[dig]="f -ignore-swap s: -size=s" + subcommands_opts[lock]="f -force -ignore-swap s: -size=s k: -key=k U: -uid=U G: -gid=G -sudo-pwd: -tomb-pwd:" subcommands_opts[passwd]="f -ignore-swap -kdf: -tomb-old-pwd: -tomb-pwd: " subcommands_opts[close]="-sudo-pwd: U: -uid=U G: -gid=G" @@ -2053,7 +2204,11 @@ main() { dig) dig_tomb ${=PARAM} ;; - + lock) + check_priv + lock_tomb_with_key ${=PARAM} + ;; + mount|open) check_priv mount_tomb $PARAM[1] $PARAM[2]