|  | #!/usr/bin/env bash | 
|  | # group: rw | 
|  | # | 
|  | # Test encryption key management with luks | 
|  | # Based on 134 | 
|  | # | 
|  | # Copyright (C) 2019 Red Hat, Inc. | 
|  | # | 
|  | # This program is free software; you can redistribute it and/or modify | 
|  | # it under the terms of the GNU General Public License as published by | 
|  | # the Free Software Foundation; either version 2 of the License, or | 
|  | # (at your option) any later version. | 
|  | # | 
|  | # This program is distributed in the hope that it will be useful, | 
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | # GNU General Public License for more details. | 
|  | # | 
|  | # You should have received a copy of the GNU General Public License | 
|  | # along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
|  | # | 
|  |  | 
|  | # creator | 
|  | owner=mlevitsk@redhat.com | 
|  |  | 
|  | seq=`basename $0` | 
|  | echo "QA output created by $seq" | 
|  |  | 
|  | status=1	# failure is the default! | 
|  |  | 
|  | _cleanup() | 
|  | { | 
|  | _cleanup_test_img | 
|  | } | 
|  | trap "_cleanup; exit \$status" 0 1 2 3 15 | 
|  |  | 
|  | # get standard environment, filters and checks | 
|  | . ./common.rc | 
|  | . ./common.filter | 
|  |  | 
|  | _supported_fmt qcow2 luks | 
|  | _supported_proto file fuse #TODO | 
|  | _require_working_luks | 
|  |  | 
|  | QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT | 
|  |  | 
|  | if [ "$IMGFMT" = "qcow2" ] ; then | 
|  | PR="encrypt." | 
|  | EXTRA_IMG_ARGS="-o encrypt.format=luks" | 
|  | fi | 
|  |  | 
|  |  | 
|  | # secrets: you are supposed to see the password as *******, see :-) | 
|  | S0="--object secret,id=sec0,data=hunter0" | 
|  | S1="--object secret,id=sec1,data=hunter1" | 
|  | S2="--object secret,id=sec2,data=hunter2" | 
|  | S3="--object secret,id=sec3,data=hunter3" | 
|  | S4="--object secret,id=sec4,data=hunter4" | 
|  | SECRETS="$S0 $S1 $S2 $S3 $S4" | 
|  |  | 
|  | # image with given secret | 
|  | IMGS0="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec0" | 
|  | IMGS1="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec1" | 
|  | IMGS2="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec2" | 
|  | IMGS3="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec3" | 
|  | IMGS4="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec4" | 
|  |  | 
|  |  | 
|  | echo "== creating a test image ==" | 
|  | _make_test_img $S0 $EXTRA_IMG_ARGS -o ${PR}key-secret=sec0,${PR}iter-time=10 32M | 
|  |  | 
|  | echo | 
|  | echo "== test that key 0 opens the image ==" | 
|  | $QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir | 
|  |  | 
|  | echo | 
|  | echo "== adding a password to slot 4 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec4,${PR}iter-time=10,${PR}keyslot=4 | 
|  | echo "== adding a password to slot 1 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}iter-time=10 | 
|  | echo "== adding a password to slot 3 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10,${PR}keyslot=3 | 
|  |  | 
|  | echo "== adding a password to slot 2 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec2,${PR}iter-time=10 | 
|  |  | 
|  |  | 
|  | echo "== erase slot 4 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=4 | _filter_img_create | 
|  |  | 
|  |  | 
|  | echo | 
|  | echo "== all secrets should work ==" | 
|  | for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir | 
|  | done | 
|  |  | 
|  | echo | 
|  | echo "== erase slot 0 and try it ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec0 | _filter_img_create | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir | 
|  |  | 
|  | echo | 
|  | echo "== erase slot 2 and try it ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=2 | _filter_img_create | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMGS2 | _filter_qemu_io | _filter_testdir | 
|  |  | 
|  |  | 
|  | # at this point slots 1 and 3 should be active | 
|  |  | 
|  | echo | 
|  | echo "== filling  4 slots with secret 2 ==" | 
|  | for ((i = 0; i < 4; i++)); do | 
|  | $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec2,${PR}iter-time=10 | 
|  | done | 
|  |  | 
|  | echo | 
|  | echo "== adding secret 0 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec0,${PR}iter-time=10 | 
|  |  | 
|  | echo | 
|  | echo "== adding secret 3 (last slot) ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10 | 
|  |  | 
|  | echo | 
|  | echo "== trying to add another slot (should fail) ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS2 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10 | 
|  |  | 
|  | echo | 
|  | echo "== all secrets should work again ==" | 
|  | for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir | 
|  | done | 
|  |  | 
|  |  | 
|  | echo | 
|  |  | 
|  | echo "== erase all keys of secret 2==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec2 | 
|  |  | 
|  | echo "== erase all keys of secret 1==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec1 | 
|  |  | 
|  | echo "== erase all keys of secret 0==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=inactive,${PR}old-secret=sec0 | 
|  |  | 
|  | echo "== erasing secret3 will fail now since it is the only secret (in 3 slots) ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=inactive,${PR}old-secret=sec3 | 
|  |  | 
|  | echo | 
|  | echo "== only secret3 should work now  ==" | 
|  | for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir | 
|  | done | 
|  |  | 
|  | echo | 
|  | echo "== add secret0  ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec0,${PR}iter-time=10 | 
|  |  | 
|  | echo "== erase secret3 ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=inactive,${PR}old-secret=sec3 | 
|  |  | 
|  | echo | 
|  | echo "== only secret0 should work now  ==" | 
|  | for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir | 
|  | done | 
|  |  | 
|  | echo | 
|  | echo "== replace secret0 with secret1 (should fail)  ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}keyslot=0 | 
|  |  | 
|  | echo | 
|  | echo "== replace secret0 with secret1 with force (should work)  ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}iter-time=10,${PR}keyslot=0 --force | 
|  |  | 
|  | echo | 
|  | echo "== only secret1 should work now  ==" | 
|  | for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir | 
|  | done | 
|  |  | 
|  |  | 
|  | echo | 
|  | echo "== erase last secret (should fail)  ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=0 | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec1 | 
|  |  | 
|  |  | 
|  | echo "== erase non existing secrets (should fail)  ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec5 --force | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec0 --force | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=1 --force | 
|  |  | 
|  | echo | 
|  | echo "== erase last secret with force by slot (should work)  ==" | 
|  | $QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=0 --force | 
|  |  | 
|  | echo | 
|  | echo "== we have no secrets now, data is lost forever ==" | 
|  | for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do | 
|  | $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir | 
|  | done | 
|  |  | 
|  | # success, all done | 
|  | echo "*** done" | 
|  | rm -f $seq.full | 
|  | status=0 | 
|  |  |