733 lines
22 KiB
Diff
733 lines
22 KiB
Diff
|
From e5f6d87d5c71f3faf0c0dbe38534fd3eab30f43e Mon Sep 17 00:00:00 2001
|
||
|
From: Sergio Correia <scorreia@redhat.com>
|
||
|
Date: Wed, 13 May 2020 23:51:04 -0300
|
||
|
Subject: [PATCH 2/8] Fix clevis luks unlock and add related tests
|
||
|
|
||
|
---
|
||
|
src/luks/clevis-luks-common-functions | 35 ++++++
|
||
|
src/luks/clevis-luks-unlock | 68 ++++++++++++
|
||
|
src/luks/clevis-luks-unlock.in | 130 ----------------------
|
||
|
src/luks/meson.build | 10 +-
|
||
|
src/luks/tests/meson.build | 40 +++++++
|
||
|
src/luks/tests/tests-common-functions.in | 134 +++++++++++++++++++++--
|
||
|
src/luks/tests/unlock-tang-luks1 | 83 ++++++++++++++
|
||
|
src/luks/tests/unlock-tang-luks2 | 83 ++++++++++++++
|
||
|
8 files changed, 439 insertions(+), 144 deletions(-)
|
||
|
create mode 100755 src/luks/clevis-luks-unlock
|
||
|
delete mode 100755 src/luks/clevis-luks-unlock.in
|
||
|
create mode 100755 src/luks/tests/unlock-tang-luks1
|
||
|
create mode 100755 src/luks/tests/unlock-tang-luks2
|
||
|
|
||
|
diff --git a/src/luks/clevis-luks-common-functions b/src/luks/clevis-luks-common-functions
|
||
|
index e27c444..d04fdb5 100644
|
||
|
--- a/src/luks/clevis-luks-common-functions
|
||
|
+++ b/src/luks/clevis-luks-common-functions
|
||
|
@@ -281,3 +281,38 @@ clevis_luks_read_pins_from_slot() {
|
||
|
fi
|
||
|
printf "%s: %s\n" "${SLOT}" "${cfg}"
|
||
|
}
|
||
|
+
|
||
|
+# clevis_luks_unlock_device() does the unlock of the device passed as
|
||
|
+# parameter and returns the decoded passphrase.
|
||
|
+clevis_luks_unlock_device() {
|
||
|
+ local DEV="${1}"
|
||
|
+ [ -z "${DEV}" ] && return 1
|
||
|
+
|
||
|
+ local used_slots
|
||
|
+ if ! used_slots=$(clevis_luks_used_slots "${DEV}") \
|
||
|
+ || [ -z "${used_slots}" ]; then
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+
|
||
|
+ local slt jwe passphrase
|
||
|
+ for slt in ${used_slots}; do
|
||
|
+ if ! jwe="$(clevis_luks_read_slot "${DEV}" "${slt}" 2>/dev/null)" \
|
||
|
+ || [ -z "${jwe}" ]; then
|
||
|
+ continue
|
||
|
+ fi
|
||
|
+
|
||
|
+ if ! passphrase="$(clevis decrypt < <(echo -n "${jwe}"))" \
|
||
|
+ || [ -z "${passphrase}" ]; then
|
||
|
+ continue
|
||
|
+ fi
|
||
|
+
|
||
|
+ if ! cryptsetup luksOpen --test-passphrase "${DEV}" \
|
||
|
+ --key-file <(echo -n "${passphrase}"); then
|
||
|
+ continue
|
||
|
+ fi
|
||
|
+ echo -n "${passphrase}"
|
||
|
+ return 0
|
||
|
+ done
|
||
|
+
|
||
|
+ return 1
|
||
|
+}
|
||
|
diff --git a/src/luks/clevis-luks-unlock b/src/luks/clevis-luks-unlock
|
||
|
new file mode 100755
|
||
|
index 0000000..580fde8
|
||
|
--- /dev/null
|
||
|
+++ b/src/luks/clevis-luks-unlock
|
||
|
@@ -0,0 +1,68 @@
|
||
|
+#!/bin/bash -e
|
||
|
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
||
|
+#
|
||
|
+# Copyright (c) 2016 Red Hat, Inc.
|
||
|
+# Author: Nathaniel McCallum <npmccallum@redhat.com>
|
||
|
+#
|
||
|
+# 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 3 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/>.
|
||
|
+#
|
||
|
+. clevis-luks-common-functions
|
||
|
+
|
||
|
+SUMMARY="Unlocks a LUKS volume"
|
||
|
+
|
||
|
+function usage() {
|
||
|
+ exec >&2
|
||
|
+ echo
|
||
|
+ echo "Usage: clevis luks unlock -d DEV [-n NAME]"
|
||
|
+ echo
|
||
|
+ echo "$SUMMARY":
|
||
|
+ echo
|
||
|
+ echo " -d DEV The LUKS device on which to perform unlocking"
|
||
|
+ echo
|
||
|
+ echo " -n NAME The name of the unlocked device node"
|
||
|
+ echo
|
||
|
+ exit 2
|
||
|
+}
|
||
|
+
|
||
|
+if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
|
||
|
+ echo "$SUMMARY"
|
||
|
+ exit 0
|
||
|
+fi
|
||
|
+
|
||
|
+while getopts ":d:n:" o; do
|
||
|
+ case "$o" in
|
||
|
+ d) DEV="$OPTARG";;
|
||
|
+ n) NAME="$OPTARG";;
|
||
|
+ *) usage;;
|
||
|
+ esac
|
||
|
+done
|
||
|
+
|
||
|
+if [ -z "$DEV" ]; then
|
||
|
+ echo "Did not specify a device!" >&2
|
||
|
+ usage
|
||
|
+fi
|
||
|
+
|
||
|
+if ! cryptsetup isLuks "$DEV"; then
|
||
|
+ echo "$DEV is not a LUKS device!" >&2
|
||
|
+ exit 1
|
||
|
+fi
|
||
|
+
|
||
|
+NAME="${NAME:-luks-"$(cryptsetup luksUUID "$DEV")"}"
|
||
|
+
|
||
|
+if ! pt=$(clevis_luks_unlock_device "${DEV}"); then
|
||
|
+ echo "${DEV} could not be opened." >&2
|
||
|
+ exit 1
|
||
|
+fi
|
||
|
+
|
||
|
+cryptsetup open -d- "${DEV}" "${NAME}" < <(echo -n "${pt}")
|
||
|
diff --git a/src/luks/clevis-luks-unlock.in b/src/luks/clevis-luks-unlock.in
|
||
|
deleted file mode 100755
|
||
|
index aa3134b..0000000
|
||
|
--- a/src/luks/clevis-luks-unlock.in
|
||
|
+++ /dev/null
|
||
|
@@ -1,130 +0,0 @@
|
||
|
-#!/bin/bash -e
|
||
|
-# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
||
|
-#
|
||
|
-# Copyright (c) 2016 Red Hat, Inc.
|
||
|
-# Author: Nathaniel McCallum <npmccallum@redhat.com>
|
||
|
-#
|
||
|
-# 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 3 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/>.
|
||
|
-#
|
||
|
-
|
||
|
-SUMMARY="Unlocks a LUKS volume"
|
||
|
-UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
|
||
|
-
|
||
|
-# We require cryptsetup >= 2.0.4 to fully support LUKSv2.
|
||
|
-# Support is determined at build time.
|
||
|
-function luks2_supported() {
|
||
|
- return @OLD_CRYPTSETUP@
|
||
|
-}
|
||
|
-
|
||
|
-function usage() {
|
||
|
- exec >&2
|
||
|
- echo
|
||
|
- echo "Usage: clevis luks unlock -d DEV [-n NAME]"
|
||
|
- echo
|
||
|
- echo "$SUMMARY":
|
||
|
- echo
|
||
|
- echo " -d DEV The LUKS device on which to perform unlocking"
|
||
|
- echo
|
||
|
- echo " -n NAME The name of the unlocked device node"
|
||
|
- echo
|
||
|
- exit 2
|
||
|
-}
|
||
|
-
|
||
|
-if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
|
||
|
- echo "$SUMMARY"
|
||
|
- exit 0
|
||
|
-fi
|
||
|
-
|
||
|
-while getopts ":d:n:" o; do
|
||
|
- case "$o" in
|
||
|
- d) DEV="$OPTARG";;
|
||
|
- n) NAME="$OPTARG";;
|
||
|
- *) usage;;
|
||
|
- esac
|
||
|
-done
|
||
|
-
|
||
|
-if [ -z "$DEV" ]; then
|
||
|
- echo "Did not specify a device!" >&2
|
||
|
- usage
|
||
|
-fi
|
||
|
-
|
||
|
-if ! cryptsetup isLuks "$DEV"; then
|
||
|
- echo "$DEV is not a LUKS device!" >&2
|
||
|
- exit 1
|
||
|
-fi
|
||
|
-
|
||
|
-if luks2_supported; then
|
||
|
- if cryptsetup isLuks --type luks1 "$DEV"; then
|
||
|
- luks_type="luks1"
|
||
|
- elif cryptsetup isLuks --type luks2 "$DEV";then
|
||
|
- luks_type="luks2"
|
||
|
- else
|
||
|
- echo "$DEV is not a supported LUKS device!" >&2
|
||
|
- exit 1
|
||
|
- fi
|
||
|
-else
|
||
|
- luks_type="luks1"
|
||
|
-fi
|
||
|
-NAME="${NAME:-luks-"$(cryptsetup luksUUID "$DEV")"}"
|
||
|
-
|
||
|
-luks1_decrypt() {
|
||
|
- luksmeta load "$@" \
|
||
|
- | clevis decrypt
|
||
|
-
|
||
|
- local rc
|
||
|
- for rc in "${PIPESTATUS[@]}"; do
|
||
|
- [ $rc -eq 0 ] || return $rc
|
||
|
- done
|
||
|
- return 0
|
||
|
-}
|
||
|
-
|
||
|
-luks2_decrypt() {
|
||
|
- # jose jwe fmt -c outputs extra \n, so clean it up
|
||
|
- cryptsetup token export "$@" \
|
||
|
- | jose fmt -j- -Og jwe -o- \
|
||
|
- | jose jwe fmt -i- -c \
|
||
|
- | tr -d '\n' \
|
||
|
- | clevis decrypt
|
||
|
-
|
||
|
- local rc
|
||
|
- for rc in "${PIPESTATUS[@]}"; do
|
||
|
- [ $rc -eq 0 ] || return $rc
|
||
|
- done
|
||
|
- return 0
|
||
|
-}
|
||
|
-
|
||
|
-if [ "$luks_type" == "luks1" ]; then
|
||
|
- while read -r slot state uuid; do
|
||
|
- [ "$state" == "active" ] || continue
|
||
|
- [ "$uuid" == "$UUID" ] || continue
|
||
|
-
|
||
|
- pt="$(luks1_decrypt -d $DEV -s $slot -u $UUID)" \
|
||
|
- || continue
|
||
|
- exec cryptsetup open -d- "$DEV" "$NAME" < <(
|
||
|
- echo -n "$pt"
|
||
|
- )
|
||
|
- done < <(luksmeta show -d "$DEV")
|
||
|
-
|
||
|
-elif [ "$luks_type" == "luks2" ]; then
|
||
|
- while read -r id; do
|
||
|
- pt="$(luks2_decrypt --token-id "$id" "$DEV")" \
|
||
|
- || continue
|
||
|
- exec cryptsetup open -d- "$DEV" "$NAME" < <(
|
||
|
- echo -n "$pt"
|
||
|
- )
|
||
|
- done < <(cryptsetup luksDump "$DEV" | sed -rn 's|^\s+([0-9]+): clevis|\1|p')
|
||
|
-fi
|
||
|
-
|
||
|
-echo "$DEV could not be opened." >&2
|
||
|
-exit 1
|
||
|
diff --git a/src/luks/meson.build b/src/luks/meson.build
|
||
|
index bbba63f..0d24f8d 100644
|
||
|
--- a/src/luks/meson.build
|
||
|
+++ b/src/luks/meson.build
|
||
|
@@ -21,9 +21,7 @@ clevis_luks_bind = configure_file(input: 'clevis-luks-bind.in',
|
||
|
clevis_luks_unbind = configure_file(input: 'clevis-luks-unbind.in',
|
||
|
output: 'clevis-luks-unbind',
|
||
|
configuration: luksmeta_data)
|
||
|
-clevis_luks_unlock = configure_file(input: 'clevis-luks-unlock.in',
|
||
|
- output: 'clevis-luks-unlock',
|
||
|
- configuration: luksmeta_data)
|
||
|
+
|
||
|
if libcryptsetup.found() and luksmeta.found() and pwmake.found()
|
||
|
subdir('systemd')
|
||
|
subdir('udisks2')
|
||
|
@@ -31,18 +29,18 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found()
|
||
|
bins += clevis_luks_unbind
|
||
|
mans += join_paths(meson.current_source_dir(), 'clevis-luks-unbind.1')
|
||
|
|
||
|
- bins += clevis_luks_unlock
|
||
|
- mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlock.1')
|
||
|
-
|
||
|
bins += clevis_luks_bind
|
||
|
mans += join_paths(meson.current_source_dir(), 'clevis-luks-bind.1')
|
||
|
|
||
|
mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlockers.7')
|
||
|
|
||
|
bins += join_paths(meson.current_source_dir(), 'clevis-luks-common-functions')
|
||
|
+
|
||
|
bins += join_paths(meson.current_source_dir(), 'clevis-luks-list')
|
||
|
mans += join_paths(meson.current_source_dir(), 'clevis-luks-list.1')
|
||
|
|
||
|
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-unlock')
|
||
|
+ mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlock.1')
|
||
|
else
|
||
|
warning('Will not install LUKS support due to missing dependencies!')
|
||
|
endif
|
||
|
diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build
|
||
|
index 2e0fb92..9a16b42 100644
|
||
|
--- a/src/luks/tests/meson.build
|
||
|
+++ b/src/luks/tests/meson.build
|
||
|
@@ -1,6 +1,30 @@
|
||
|
# We use jq for comparing the pin config in the clevis luks list tests.
|
||
|
jq = find_program('jq', required: false)
|
||
|
|
||
|
+# we use systemd-socket-activate for running test tang servers.
|
||
|
+actv = find_program(
|
||
|
+ 'systemd-socket-activate',
|
||
|
+ 'systemd-activate',
|
||
|
+ required: false
|
||
|
+)
|
||
|
+
|
||
|
+kgen = find_program(
|
||
|
+ join_paths(libexecdir, 'tangd-keygen'),
|
||
|
+ join_paths(get_option('prefix'), get_option('libdir'), 'tangd-keygen'),
|
||
|
+ join_paths(get_option('prefix'), get_option('libexecdir'), 'tangd-keygen'),
|
||
|
+ join_paths('/', 'usr', get_option('libdir'), 'tangd-keygen'),
|
||
|
+ join_paths('/', 'usr', get_option('libexecdir'), 'tangd-keygen'),
|
||
|
+ required: false
|
||
|
+)
|
||
|
+tang = find_program(
|
||
|
+ join_paths(libexecdir, 'tangd'),
|
||
|
+ join_paths(get_option('prefix'), get_option('libdir'), 'tangd'),
|
||
|
+ join_paths(get_option('prefix'), get_option('libexecdir'), 'tangd'),
|
||
|
+ join_paths('/', 'usr', get_option('libdir'), 'tangd'),
|
||
|
+ join_paths('/', 'usr', get_option('libexecdir'), 'tangd'),
|
||
|
+ required: false
|
||
|
+)
|
||
|
+
|
||
|
common_functions = configure_file(input: 'tests-common-functions.in',
|
||
|
output: 'tests-common-functions',
|
||
|
configuration: luksmeta_data,
|
||
|
@@ -24,6 +48,14 @@ env.prepend('PATH',
|
||
|
separator: ':'
|
||
|
)
|
||
|
|
||
|
+has_tang = false
|
||
|
+if actv.found() and kgen.found() and tang.found()
|
||
|
+ has_tang = true
|
||
|
+ env.set('SD_ACTIVATE', actv.path())
|
||
|
+ env.set('TANGD_KEYGEN', kgen.path())
|
||
|
+ env.set('TANGD', tang.path())
|
||
|
+endif
|
||
|
+
|
||
|
test('bind-wrong-pass-luks1', find_program('bind-wrong-pass-luks1'), env: env)
|
||
|
test('bind-luks1', find_program('bind-luks1'), env: env)
|
||
|
test('unbind-unbound-slot-luks1', find_program('unbind-unbound-slot-luks1'), env: env)
|
||
|
@@ -42,6 +74,10 @@ else
|
||
|
warning('Will not run "clevis luks list" tests due to missing jq dependency')
|
||
|
endif
|
||
|
|
||
|
+if has_tang
|
||
|
+ test('unlock-tang-luks1', find_program('unlock-tang-luks1'), env: env, timeout: 90)
|
||
|
+endif
|
||
|
+
|
||
|
# LUKS2 tests go here, and they get included if we get support for it, based
|
||
|
# on the cryptsetup version.
|
||
|
# Binding LUKS2 takes longer, so timeout is increased for a few tests.
|
||
|
@@ -56,4 +92,8 @@ if luksmeta_data.get('OLD_CRYPTSETUP') == '0'
|
||
|
test('list-tang-luks2', find_program('list-tang-luks2'), env: env, timeout: 60)
|
||
|
test('list-sss-tang-luks2', find_program('list-sss-tang-luks2'), env: env, timeout: 60)
|
||
|
endif
|
||
|
+
|
||
|
+ if has_tang
|
||
|
+ test('unlock-tang-luks2', find_program('unlock-tang-luks2'), env: env, timeout: 120)
|
||
|
+ endif
|
||
|
endif
|
||
|
diff --git a/src/luks/tests/tests-common-functions.in b/src/luks/tests/tests-common-functions.in
|
||
|
index 90420d1..7b3fdad 100755
|
||
|
--- a/src/luks/tests/tests-common-functions.in
|
||
|
+++ b/src/luks/tests/tests-common-functions.in
|
||
|
@@ -56,7 +56,7 @@ new_device() {
|
||
|
|
||
|
# Some builders fail if the cryptsetup steps are not ran as root, so let's
|
||
|
# skip the test now if not running as root.
|
||
|
- if [ $(id -u) != 0 ]; then
|
||
|
+ if [ "$(id -u)" != 0 ]; then
|
||
|
skip_test "WARNING: You must be root to run this test; test skipped."
|
||
|
fi
|
||
|
|
||
|
@@ -74,9 +74,9 @@ new_device() {
|
||
|
return 0
|
||
|
fi
|
||
|
|
||
|
- fallocate -l16M "${DEV}"
|
||
|
- local extra_options='--pbkdf pbkdf2 --pbkdf-force-iterations 1000'
|
||
|
- cryptsetup luksFormat --type "${LUKS}" ${extra_options} --batch-mode \
|
||
|
+ fallocate -l64M "${DEV}"
|
||
|
+ cryptsetup luksFormat --type "${LUKS}" --pbkdf pbkdf2 \
|
||
|
+ --pbkdf-force-iterations 1000 --batch-mode \
|
||
|
--force-password "${DEV}" <<< "${PASS}"
|
||
|
# Caching the just-formatted device for possible reuse.
|
||
|
cp -f "${DEV}" "${DEV_CACHED}"
|
||
|
@@ -90,7 +90,7 @@ new_device_keyfile() {
|
||
|
|
||
|
# Some builders fail if the cryptsetup steps are not ran as root, so let's
|
||
|
# skip the test now if not running as root.
|
||
|
- if [ $(id -u) != 0 ]; then
|
||
|
+ if [ "$(id -u)" != 0 ]; then
|
||
|
skip_test "WARNING: You must be root to run this test; test skipped."
|
||
|
fi
|
||
|
|
||
|
@@ -98,9 +98,9 @@ new_device_keyfile() {
|
||
|
error "Invalid keyfile (${KEYFILE})."
|
||
|
fi
|
||
|
|
||
|
- fallocate -l16M "${DEV}"
|
||
|
- local extra_options='--pbkdf pbkdf2 --pbkdf-force-iterations 1000'
|
||
|
- cryptsetup luksFormat --type "${LUKS}" ${extra_options} --batch-mode \
|
||
|
+ fallocate -l64M "${DEV}"
|
||
|
+ cryptsetup luksFormat --type "${LUKS}" --pbkdf pbkdf2 \
|
||
|
+ --pbkdf-force-iterations 1000 --batch-mode \
|
||
|
"${DEV}" "${KEYFILE}"
|
||
|
}
|
||
|
|
||
|
@@ -112,4 +112,122 @@ pin_cfg_equal() {
|
||
|
<(jq -S . < <(echo -n "${cfg2}"))
|
||
|
}
|
||
|
|
||
|
+# Get a random port to be used with a test tang server.
|
||
|
+get_random_port() {
|
||
|
+ shuf -i 1024-65535 -n 1
|
||
|
+}
|
||
|
+
|
||
|
+# Removes tang rotated keys from the test server.
|
||
|
+tang_remove_rotated_keys() {
|
||
|
+ local basedir="${1}"
|
||
|
+
|
||
|
+ if [ -z "${basedir}" ]; then
|
||
|
+ echo "Please pass a valid base directory for tang"
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+
|
||
|
+ local db="${basedir}/db"
|
||
|
+ mkdir -p "${db}"
|
||
|
+
|
||
|
+ pushd "${db}"
|
||
|
+ find . -name ".*.jwk" -exec rm -f {} \;
|
||
|
+ popd
|
||
|
+}
|
||
|
+
|
||
|
+# Creates new keys for the test tang server.
|
||
|
+tang_new_keys() {
|
||
|
+ local basedir="${1}"
|
||
|
+ local rotate="${2}"
|
||
|
+
|
||
|
+ if [ -z "${basedir}" ]; then
|
||
|
+ echo "Please pass a valid base directory for tang"
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+
|
||
|
+ [ -z "${TANGD_KEYGEN}" ] && skip_test "WARNING: TANGD_KEYGEN is not defined."
|
||
|
+
|
||
|
+ local db="${basedir}/db"
|
||
|
+ mkdir -p "${db}"
|
||
|
+
|
||
|
+ if [ -n "${rotate}" ]; then
|
||
|
+ pushd "${db}"
|
||
|
+ local k
|
||
|
+ k=$(find . -name "*.jwk" | wc -l)
|
||
|
+ if [ "${k}" -gt 0 ]; then
|
||
|
+ for k in *.jwk; do
|
||
|
+ mv -f -- "${k}" ".${k}"
|
||
|
+ done
|
||
|
+ fi
|
||
|
+ popd
|
||
|
+ fi
|
||
|
+
|
||
|
+ "${TANGD_KEYGEN}" "${db}"
|
||
|
+
|
||
|
+ return 0
|
||
|
+}
|
||
|
+
|
||
|
+# Start a test tang server.
|
||
|
+tang_run() {
|
||
|
+ local basedir="${1}"
|
||
|
+ local port="${2}"
|
||
|
+
|
||
|
+ if [ -z "${basedir}" ]; then
|
||
|
+ echo "Please pass a valid base directory for tang" >&2
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+
|
||
|
+ if [ -z "${port}" ]; then
|
||
|
+ echo "Please pass a valid port for tang" >&2
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+
|
||
|
+ if ! tang_new_keys "${basedir}"; then
|
||
|
+ echo "Error creating new keys for tang server" >&2
|
||
|
+ return 1
|
||
|
+ fi
|
||
|
+
|
||
|
+ local KEYS="${basedir}/db"
|
||
|
+
|
||
|
+ local inetd='--inetd'
|
||
|
+ [ "${SD_ACTIVATE##*/}" = "systemd-activate" ] && inetd=
|
||
|
+
|
||
|
+ local pid pidfile
|
||
|
+ pidfile="${basedir}/tang.pid"
|
||
|
+
|
||
|
+ "${SD_ACTIVATE}" ${inetd} -l "${TANG_HOST}":"${port}" \
|
||
|
+ -a "${TANGD}" "${KEYS}" &
|
||
|
+ pid=$!
|
||
|
+ echo "${pid}" > "${pidfile}"
|
||
|
+}
|
||
|
+
|
||
|
+# Stop tang server.
|
||
|
+tang_stop() {
|
||
|
+ local basedir="${1}"
|
||
|
+ local pidfile="${basedir}/tang.pid"
|
||
|
+ [ -f "${pidfile}" ] || return 0
|
||
|
+
|
||
|
+ local pid
|
||
|
+ pid=$(<"${pidfile}")
|
||
|
+ kill "${pid}"
|
||
|
+}
|
||
|
+
|
||
|
+# Wait for the tang server to be operational.
|
||
|
+tang_wait_until_ready() {
|
||
|
+ local port="${1}"
|
||
|
+ while ! curl --output /dev/null --silent --fail \
|
||
|
+ http://"${TANG_HOST}":"${port}"/adv; do
|
||
|
+ sleep 0.1
|
||
|
+ echo -n . >&2
|
||
|
+ done
|
||
|
+}
|
||
|
+
|
||
|
+# Get tang advertisement.
|
||
|
+tang_get_adv() {
|
||
|
+ local port="${1}"
|
||
|
+ local adv="${2}"
|
||
|
+
|
||
|
+ curl -o "${adv}" http://"${TANG_HOST}":"${port}"/adv
|
||
|
+}
|
||
|
+
|
||
|
+export TANG_HOST=127.0.0.1
|
||
|
export DEFAULT_PASS='just-some-test-password-here'
|
||
|
diff --git a/src/luks/tests/unlock-tang-luks1 b/src/luks/tests/unlock-tang-luks1
|
||
|
new file mode 100755
|
||
|
index 0000000..841ba01
|
||
|
--- /dev/null
|
||
|
+++ b/src/luks/tests/unlock-tang-luks1
|
||
|
@@ -0,0 +1,83 @@
|
||
|
+#!/bin/bash -ex
|
||
|
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
||
|
+#
|
||
|
+# Copyright (c) 2020 Red Hat, Inc.
|
||
|
+# Author: Sergio Correia <scorreia@redhat.com>
|
||
|
+#
|
||
|
+# 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 3 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/>.
|
||
|
+
|
||
|
+TEST=$(basename "${0}")
|
||
|
+. tests-common-functions
|
||
|
+
|
||
|
+. clevis-luks-common-functions
|
||
|
+
|
||
|
+on_exit() {
|
||
|
+ [ ! -d "${TMP}" ] && return 0
|
||
|
+ tang_stop "${TMP}"
|
||
|
+ rm -rf "${TMP}"
|
||
|
+}
|
||
|
+
|
||
|
+trap 'on_exit' EXIT
|
||
|
+trap 'on_exit' ERR
|
||
|
+
|
||
|
+TMP="$(mktemp -d)"
|
||
|
+
|
||
|
+port=$(get_random_port)
|
||
|
+tang_run "${TMP}" "${port}" &
|
||
|
+tang_wait_until_ready "${port}"
|
||
|
+
|
||
|
+url="http://${TANG_HOST}:${port}"
|
||
|
+adv="${TMP}/adv"
|
||
|
+tang_get_adv "${port}" "${adv}"
|
||
|
+
|
||
|
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
|
||
|
+
|
||
|
+# LUKS1.
|
||
|
+DEV="${TMP}/luks1-device"
|
||
|
+new_device "luks1" "${DEV}"
|
||
|
+
|
||
|
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
|
||
|
+ error "${TEST}: Bind should have succeeded."
|
||
|
+fi
|
||
|
+
|
||
|
+if ! clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we were unable to unlock ${DEV}."
|
||
|
+fi
|
||
|
+
|
||
|
+# Let's rotate the tang keys and add another binding with the new key.
|
||
|
+tang_new_keys "${TMP}" "rotate-keys"
|
||
|
+
|
||
|
+# Unlock should still work now.
|
||
|
+if ! clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we should still be able to unlock ${DEV}"
|
||
|
+fi
|
||
|
+
|
||
|
+# Now let's remove the rotated keys.
|
||
|
+tang_remove_rotated_keys "${TMP}"
|
||
|
+
|
||
|
+# Unlock should not work anymore.
|
||
|
+if clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we should not be able to unlock ${DEV}"
|
||
|
+fi
|
||
|
+
|
||
|
+# Now let's add another binding with the new keys.
|
||
|
+tang_get_adv "${port}" "${adv}" # Updating the advertisement.
|
||
|
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
|
||
|
+ error "${TEST}: Bind should have succeeded."
|
||
|
+fi
|
||
|
+
|
||
|
+# Unlock should work again, using the new keys.
|
||
|
+if ! clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we should be able to unlock ${DEV} with the new keys"
|
||
|
+fi
|
||
|
diff --git a/src/luks/tests/unlock-tang-luks2 b/src/luks/tests/unlock-tang-luks2
|
||
|
new file mode 100755
|
||
|
index 0000000..81822fb
|
||
|
--- /dev/null
|
||
|
+++ b/src/luks/tests/unlock-tang-luks2
|
||
|
@@ -0,0 +1,83 @@
|
||
|
+#!/bin/bash -ex
|
||
|
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
||
|
+#
|
||
|
+# Copyright (c) 2020 Red Hat, Inc.
|
||
|
+# Author: Sergio Correia <scorreia@redhat.com>
|
||
|
+#
|
||
|
+# 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 3 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/>.
|
||
|
+
|
||
|
+TEST=$(basename "${0}")
|
||
|
+. tests-common-functions
|
||
|
+
|
||
|
+. clevis-luks-common-functions
|
||
|
+
|
||
|
+on_exit() {
|
||
|
+ [ ! -d "${TMP}" ] && return 0
|
||
|
+ tang_stop "${TMP}"
|
||
|
+ rm -rf "${TMP}"
|
||
|
+}
|
||
|
+
|
||
|
+trap 'on_exit' EXIT
|
||
|
+trap 'on_exit' ERR
|
||
|
+
|
||
|
+TMP="$(mktemp -d)"
|
||
|
+
|
||
|
+port=$(get_random_port)
|
||
|
+tang_run "${TMP}" "${port}" &
|
||
|
+tang_wait_until_ready "${port}"
|
||
|
+
|
||
|
+url="http://${TANG_HOST}:${port}"
|
||
|
+adv="${TMP}/adv"
|
||
|
+tang_get_adv "${port}" "${adv}"
|
||
|
+
|
||
|
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
|
||
|
+
|
||
|
+# LUKS2.
|
||
|
+DEV="${TMP}/luks2-device"
|
||
|
+new_device "luks2" "${DEV}"
|
||
|
+
|
||
|
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
|
||
|
+ error "${TEST}: Bind should have succeeded."
|
||
|
+fi
|
||
|
+
|
||
|
+if ! clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we were unable to unlock ${DEV}."
|
||
|
+fi
|
||
|
+
|
||
|
+# Let's rotate the tang keys and add another binding with the new key.
|
||
|
+tang_new_keys "${TMP}" "rotate-keys"
|
||
|
+
|
||
|
+# Unlock should still work now.
|
||
|
+if ! clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we should still be able to unlock ${DEV}"
|
||
|
+fi
|
||
|
+
|
||
|
+# Now let's remove the rotated keys.
|
||
|
+tang_remove_rotated_keys "${TMP}"
|
||
|
+
|
||
|
+# Unlock should not work anymore.
|
||
|
+if clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we should not be able to unlock ${DEV}"
|
||
|
+fi
|
||
|
+
|
||
|
+# Now let's add another binding with the new keys.
|
||
|
+tang_get_adv "${port}" "${adv}" # Updating the advertisement.
|
||
|
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
|
||
|
+ error "${TEST}: Bind should have succeeded."
|
||
|
+fi
|
||
|
+
|
||
|
+# Unlock should work again, using the new keys.
|
||
|
+if ! clevis_luks_unlock_device "${DEV}"; then
|
||
|
+ error "${TEST}: we should be able to unlock ${DEV} with the new keys"
|
||
|
+fi
|
||
|
--
|
||
|
2.18.4
|
||
|
|