|
|
524513 |
From 69556d143544a72f84e9daf25924e3ae5132ce1a Mon Sep 17 00:00:00 2001
|
|
|
524513 |
From: Sergio Correia <scorreia@redhat.com>
|
|
|
524513 |
Date: Sat, 30 Nov 2019 14:58:43 -0500
|
|
|
524513 |
Subject: [PATCH] Add the option to extract luks passphrase used for binding
|
|
|
524513 |
|
|
|
524513 |
Usage:
|
|
|
524513 |
|
|
|
524513 |
clevis luks pass -d /dev/sda1 -s 1
|
|
|
524513 |
<passphrase here>
|
|
|
524513 |
---
|
|
|
524513 |
src/luks/clevis-luks-pass | 69 +++++++++++++++++++++++++++++
|
|
|
524513 |
src/luks/clevis-luks-pass.1.adoc | 43 ++++++++++++++++++
|
|
|
524513 |
src/luks/meson.build | 3 ++
|
|
|
524513 |
src/luks/tests/meson.build | 11 +++++
|
|
|
524513 |
src/luks/tests/pass-tang-luks1 | 75 ++++++++++++++++++++++++++++++++
|
|
|
524513 |
src/luks/tests/pass-tang-luks2 | 75 ++++++++++++++++++++++++++++++++
|
|
|
524513 |
6 files changed, 276 insertions(+)
|
|
|
524513 |
create mode 100755 src/luks/clevis-luks-pass
|
|
|
524513 |
create mode 100644 src/luks/clevis-luks-pass.1.adoc
|
|
|
524513 |
create mode 100755 src/luks/tests/pass-tang-luks1
|
|
|
524513 |
create mode 100755 src/luks/tests/pass-tang-luks2
|
|
|
524513 |
|
|
|
524513 |
diff --git a/src/luks/clevis-luks-pass b/src/luks/clevis-luks-pass
|
|
|
524513 |
new file mode 100755
|
|
|
524513 |
index 0000000..1ce8c4c
|
|
|
524513 |
--- /dev/null
|
|
|
524513 |
+++ b/src/luks/clevis-luks-pass
|
|
|
524513 |
@@ -0,0 +1,69 @@
|
|
|
524513 |
+#!/bin/bash -e
|
|
|
524513 |
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
|
|
524513 |
+#
|
|
|
524513 |
+# Copyright (c) 2019 Red Hat, Inc.
|
|
|
524513 |
+# Author: Sergio Correia <scorreia@redhat.com> - LUKS2 support.
|
|
|
524513 |
+#
|
|
|
524513 |
+# This program is free software: you can redistribute it and/or modify
|
|
|
524513 |
+# it under the terms of the GNU General Public License as published by
|
|
|
524513 |
+# the Free Software Foundation, either version 3 of the License, or
|
|
|
524513 |
+# (at your option) any later version.
|
|
|
524513 |
+#
|
|
|
524513 |
+# This program is distributed in the hope that it will be useful,
|
|
|
524513 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
524513 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
524513 |
+# GNU General Public License for more details.
|
|
|
524513 |
+#
|
|
|
524513 |
+# You should have received a copy of the GNU General Public License
|
|
|
524513 |
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
524513 |
+#
|
|
|
524513 |
+
|
|
|
524513 |
+. clevis-luks-common-functions
|
|
|
524513 |
+
|
|
|
524513 |
+SUMMARY="Returns the LUKS passphrase used for binding a particular slot."
|
|
|
524513 |
+
|
|
|
524513 |
+function usage() {
|
|
|
524513 |
+ echo >&2
|
|
|
524513 |
+ echo "Usage: clevis luks pass -d DEV -s SLT" >&2
|
|
|
524513 |
+ echo >&2
|
|
|
524513 |
+ echo "$SUMMARY": >&2
|
|
|
524513 |
+ echo >&2
|
|
|
524513 |
+ echo " -d DEV The LUKS device to extract the LUKS passphrase used for binding" >&2
|
|
|
524513 |
+ echo >&2
|
|
|
524513 |
+ echo " -s SLOT The slot number to extract the LUKS passphrase" >&2
|
|
|
524513 |
+ echo >&2
|
|
|
524513 |
+ exit 1
|
|
|
524513 |
+}
|
|
|
524513 |
+
|
|
|
524513 |
+if [ ${#} -eq 1 ] && [ "${1}" = "--summary" ]; then
|
|
|
524513 |
+ echo "${SUMMARY}"
|
|
|
524513 |
+ exit 0
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+while getopts ":d:s:" o; do
|
|
|
524513 |
+ case "$o" in
|
|
|
524513 |
+ d) DEV=${OPTARG};;
|
|
|
524513 |
+ s) SLT=${OPTARG};;
|
|
|
524513 |
+ *) usage;;
|
|
|
524513 |
+ esac
|
|
|
524513 |
+done
|
|
|
524513 |
+
|
|
|
524513 |
+if [ -z "${DEV}" ]; then
|
|
|
524513 |
+ echo "Did not specify a device!" >&2
|
|
|
524513 |
+ usage
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+if [ -z "${SLT}" ]; then
|
|
|
524513 |
+ echo "Did not specify a slot!" >&2
|
|
|
524513 |
+ usage
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+if ! jwe=$(clevis_luks_read_slot "${DEV}" "${SLT}" 2>/dev/null); then
|
|
|
524513 |
+ echo "It was not possible to read slot ${SLT} from ${DEV}!" >&2
|
|
|
524513 |
+ exit 1
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+if ! clevis decrypt < <(echo -n "${jwe}"); then
|
|
|
524513 |
+ echo "It was not possible to decrypt the passphrase associated to slot ${SLT} in {DEV}!" >&2
|
|
|
524513 |
+ exit 1
|
|
|
524513 |
+fi
|
|
|
524513 |
diff --git a/src/luks/clevis-luks-pass.1.adoc b/src/luks/clevis-luks-pass.1.adoc
|
|
|
524513 |
new file mode 100644
|
|
|
524513 |
index 0000000..fa9526a
|
|
|
524513 |
--- /dev/null
|
|
|
524513 |
+++ b/src/luks/clevis-luks-pass.1.adoc
|
|
|
524513 |
@@ -0,0 +1,43 @@
|
|
|
524513 |
+CLEVIS-LUKS-PASS(1)
|
|
|
524513 |
+===================
|
|
|
524513 |
+:doctype: manpage
|
|
|
524513 |
+
|
|
|
524513 |
+
|
|
|
524513 |
+== NAME
|
|
|
524513 |
+
|
|
|
524513 |
+clevis-luks-pass - Extracts the passphrase used for binding a particular slot in a LUKS device
|
|
|
524513 |
+
|
|
|
524513 |
+== SYNOPSIS
|
|
|
524513 |
+
|
|
|
524513 |
+*clevis luks pass* -d DEV -s SLT
|
|
|
524513 |
+
|
|
|
524513 |
+== OVERVIEW
|
|
|
524513 |
+
|
|
|
524513 |
+The *clevis luks pass* command extracts the passphrase used for binding a particular slot in a LUKS device.
|
|
|
524513 |
+For example:
|
|
|
524513 |
+
|
|
|
524513 |
+ clevis luks pass -d /dev/sda1 -s 1
|
|
|
524513 |
+
|
|
|
524513 |
+== OPTIONS
|
|
|
524513 |
+
|
|
|
524513 |
+* *-d* _DEV_ :
|
|
|
524513 |
+ The LUKS device on which to extract a passphrase from
|
|
|
524513 |
+
|
|
|
524513 |
+* *-s* _SLT_ :
|
|
|
524513 |
+ The slot to use for extracting the passphrase
|
|
|
524513 |
+
|
|
|
524513 |
+== EXAMPLE
|
|
|
524513 |
+
|
|
|
524513 |
+ clevis luks pass -d /dev/sda1 -s 1
|
|
|
524513 |
+ <passphrase here>
|
|
|
524513 |
+
|
|
|
524513 |
+Note that the output of *clevis luks pass* might be non-printable, in which case it would be better to redirect its output to a file and use it as a key
|
|
|
524513 |
+file together with cryptsetup. For instance:
|
|
|
524513 |
+
|
|
|
524513 |
+ clevis luks pass -d /dev/sda1 -s 1 > slot1-passphrase
|
|
|
524513 |
+
|
|
|
524513 |
+And the file slot1-passphrase will contain the passphrase associated with slot #1 in /dev/sda1.
|
|
|
524513 |
+
|
|
|
524513 |
+== SEE ALSO
|
|
|
524513 |
+
|
|
|
524513 |
+link:clevis-luks-unlock.1.adoc[*clevis-luks-unlock*(1)],
|
|
|
524513 |
diff --git a/src/luks/meson.build b/src/luks/meson.build
|
|
|
524513 |
index 51d82fb..b2dd724 100644
|
|
|
524513 |
--- a/src/luks/meson.build
|
|
|
524513 |
+++ b/src/luks/meson.build
|
|
|
524513 |
@@ -23,6 +23,9 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found()
|
|
|
524513 |
bins += join_paths(meson.current_source_dir(), 'clevis-luks-list')
|
|
|
524513 |
mans += join_paths(meson.current_source_dir(), 'clevis-luks-list.1')
|
|
|
524513 |
|
|
|
524513 |
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-pass')
|
|
|
524513 |
+ mans += join_paths(meson.current_source_dir(), 'clevis-luks-pass.1')
|
|
|
524513 |
+
|
|
|
524513 |
bins += join_paths(meson.current_source_dir(), 'clevis-luks-report')
|
|
|
524513 |
bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-compare')
|
|
|
524513 |
bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-decode')
|
|
|
524513 |
diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build
|
|
|
524513 |
index 6513eaa..248d2ea 100644
|
|
|
524513 |
--- a/src/luks/tests/meson.build
|
|
|
524513 |
+++ b/src/luks/tests/meson.build
|
|
|
524513 |
@@ -1,3 +1,9 @@
|
|
|
524513 |
+actv = find_program(
|
|
|
524513 |
+ 'systemd-socket-activate',
|
|
|
524513 |
+ 'systemd-activate',
|
|
|
524513 |
+ required: false
|
|
|
524513 |
+)
|
|
|
524513 |
+
|
|
|
524513 |
# We use jq for comparing the pin config in the clevis luks list tests.
|
|
|
524513 |
jq = find_program('jq', required: false)
|
|
|
524513 |
|
|
|
524513 |
@@ -15,8 +21,11 @@ env.prepend('PATH',
|
|
|
524513 |
join_paths(meson.build_root(), 'src', 'pins', 'sss'),
|
|
|
524513 |
join_paths(meson.build_root(), 'src', 'pins', 'tang'),
|
|
|
524513 |
join_paths(meson.build_root(), 'src', 'pins', 'tpm2'),
|
|
|
524513 |
+ libexecdir,
|
|
|
524513 |
+ '/usr/libexec',
|
|
|
524513 |
separator: ':'
|
|
|
524513 |
)
|
|
|
524513 |
+env.set('SD_ACTIVATE', actv.path())
|
|
|
524513 |
|
|
|
524513 |
if jq.found()
|
|
|
524513 |
test('list-recursive-luks1', find_program('list-recursive-luks1'), env: env)
|
|
|
524513 |
@@ -25,6 +34,7 @@ if jq.found()
|
|
|
524513 |
else
|
|
|
524513 |
warning('Will not run "clevis luks list" tests due to missing jq dependency')
|
|
|
524513 |
endif
|
|
|
524513 |
+test('pass-tang-luks1', find_program('pass-tang-luks1'), env: env)
|
|
|
524513 |
|
|
|
524513 |
# LUKS2 tests go here, and they get included if we get support for it, based
|
|
|
524513 |
# on the cryptsetup version.
|
|
|
524513 |
@@ -34,3 +44,4 @@ if jq.found()
|
|
|
524513 |
test('list-tang-luks2', find_program('list-tang-luks2'), env: env, timeout: 60)
|
|
|
524513 |
test('list-sss-tang-luks2', find_program('list-sss-tang-luks2'), env: env, timeout: 60)
|
|
|
524513 |
endif
|
|
|
524513 |
+test('pass-tang-luks2', find_program('pass-tang-luks2'), env: env, timeout: 60)
|
|
|
524513 |
diff --git a/src/luks/tests/pass-tang-luks1 b/src/luks/tests/pass-tang-luks1
|
|
|
524513 |
new file mode 100755
|
|
|
524513 |
index 0000000..05cdb3e
|
|
|
524513 |
--- /dev/null
|
|
|
524513 |
+++ b/src/luks/tests/pass-tang-luks1
|
|
|
524513 |
@@ -0,0 +1,75 @@
|
|
|
524513 |
+#!/bin/bash -x
|
|
|
524513 |
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
|
|
524513 |
+#
|
|
|
524513 |
+# Copyright (c) 2019 Red Hat, Inc.
|
|
|
524513 |
+# Author: Sergio Correia <scorreia@redhat.com>
|
|
|
524513 |
+#
|
|
|
524513 |
+# This program is free software: you can redistribute it and/or modify
|
|
|
524513 |
+# it under the terms of the GNU General Public License as published by
|
|
|
524513 |
+# the Free Software Foundation, either version 3 of the License, or
|
|
|
524513 |
+# (at your option) any later version.
|
|
|
524513 |
+#
|
|
|
524513 |
+# This program is distributed in the hope that it will be useful,
|
|
|
524513 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
524513 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
524513 |
+# GNU General Public License for more details.
|
|
|
524513 |
+#
|
|
|
524513 |
+# You should have received a copy of the GNU General Public License
|
|
|
524513 |
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
524513 |
+#
|
|
|
524513 |
+
|
|
|
524513 |
+TEST="${0}"
|
|
|
524513 |
+. tests-common-functions
|
|
|
524513 |
+
|
|
|
524513 |
+function on_exit() {
|
|
|
524513 |
+ if [ "$PID" ]; then kill $PID; wait $PID || true; fi
|
|
|
524513 |
+ [ -d "$TMP" ] && rm -rf $TMP
|
|
|
524513 |
+}
|
|
|
524513 |
+
|
|
|
524513 |
+trap 'on_exit' EXIT
|
|
|
524513 |
+trap 'exit' ERR
|
|
|
524513 |
+
|
|
|
524513 |
+export TMP=$(mktemp -d)
|
|
|
524513 |
+mkdir -p "${TMP}/db"
|
|
|
524513 |
+
|
|
|
524513 |
+# Generate the server keys
|
|
|
524513 |
+KEYS="$TMP/db"
|
|
|
524513 |
+tangd-keygen $TMP/db sig exc
|
|
|
524513 |
+if which tangd-update; then
|
|
|
524513 |
+ mkdir -p "${TMP}/cache"
|
|
|
524513 |
+ tangd-update "${TMP}/db" "${TMP}/cache"
|
|
|
524513 |
+ KEYS="${TMP}/cache"
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+# Start the server.
|
|
|
524513 |
+port=$(shuf -i 1024-65536 -n 1)
|
|
|
524513 |
+"${SD_ACTIVATE}" --inetd -l 127.0.0.1:"${port}" -a tangd "${KEYS}" &
|
|
|
524513 |
+export PID=$!
|
|
|
524513 |
+sleep 0.25
|
|
|
524513 |
+
|
|
|
524513 |
+url="http://localhost:${port}"
|
|
|
524513 |
+adv="${TMP}/adv"
|
|
|
524513 |
+curl "${url}/adv" -o "${adv}"
|
|
|
524513 |
+
|
|
|
524513 |
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
|
|
|
524513 |
+
|
|
|
524513 |
+# LUKS1.
|
|
|
524513 |
+DEV="${TMP}/luks1-device"
|
|
|
524513 |
+new_device "luks1" "${DEV}"
|
|
|
524513 |
+
|
|
|
524513 |
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
|
|
|
524513 |
+ error "${TEST}: Bind should have succeeded."
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+#Now let's test the passphrase.
|
|
|
524513 |
+SLT=1
|
|
|
524513 |
+PASS=$(clevis luks pass -d "${DEV}" -s "${SLT}")
|
|
|
524513 |
+echo $PASS >&2
|
|
|
524513 |
+if ! cryptsetup luksOpen --test-passphrase ""${DEV} \
|
|
|
524513 |
+ --key-file <(clevis luks pass -d "${DEV}" -s "${SLT}"); then
|
|
|
524513 |
+ error "Passphrase obtained from clevis luks pass failed."
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+kill -9 "${PID}"
|
|
|
524513 |
+! wait "${PID}"
|
|
|
524513 |
+unset PID
|
|
|
524513 |
diff --git a/src/luks/tests/pass-tang-luks2 b/src/luks/tests/pass-tang-luks2
|
|
|
524513 |
new file mode 100755
|
|
|
524513 |
index 0000000..9123aa0
|
|
|
524513 |
--- /dev/null
|
|
|
524513 |
+++ b/src/luks/tests/pass-tang-luks2
|
|
|
524513 |
@@ -0,0 +1,75 @@
|
|
|
524513 |
+#!/bin/bash -x
|
|
|
524513 |
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
|
|
|
524513 |
+#
|
|
|
524513 |
+# Copyright (c) 2019 Red Hat, Inc.
|
|
|
524513 |
+# Author: Sergio Correia <scorreia@redhat.com>
|
|
|
524513 |
+#
|
|
|
524513 |
+# This program is free software: you can redistribute it and/or modify
|
|
|
524513 |
+# it under the terms of the GNU General Public License as published by
|
|
|
524513 |
+# the Free Software Foundation, either version 3 of the License, or
|
|
|
524513 |
+# (at your option) any later version.
|
|
|
524513 |
+#
|
|
|
524513 |
+# This program is distributed in the hope that it will be useful,
|
|
|
524513 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
524513 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
524513 |
+# GNU General Public License for more details.
|
|
|
524513 |
+#
|
|
|
524513 |
+# You should have received a copy of the GNU General Public License
|
|
|
524513 |
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
524513 |
+#
|
|
|
524513 |
+
|
|
|
524513 |
+TEST="${0}"
|
|
|
524513 |
+. tests-common-functions
|
|
|
524513 |
+
|
|
|
524513 |
+function on_exit() {
|
|
|
524513 |
+ if [ "$PID" ]; then kill $PID; wait $PID || true; fi
|
|
|
524513 |
+ [ -d "$TMP" ] && rm -rf $TMP
|
|
|
524513 |
+}
|
|
|
524513 |
+
|
|
|
524513 |
+trap 'on_exit' EXIT
|
|
|
524513 |
+trap 'exit' ERR
|
|
|
524513 |
+
|
|
|
524513 |
+export TMP=$(mktemp -d)
|
|
|
524513 |
+mkdir -p "${TMP}/db"
|
|
|
524513 |
+
|
|
|
524513 |
+# Generate the server keys
|
|
|
524513 |
+KEYS="$TMP/db"
|
|
|
524513 |
+tangd-keygen $TMP/db sig exc
|
|
|
524513 |
+if which tangd-update; then
|
|
|
524513 |
+ mkdir -p "${TMP}/cache"
|
|
|
524513 |
+ tangd-update "${TMP}/db" "${TMP}/cache"
|
|
|
524513 |
+ KEYS="${TMP}/cache"
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+# Start the server.
|
|
|
524513 |
+port=$(shuf -i 1024-65536 -n 1)
|
|
|
524513 |
+"${SD_ACTIVATE}" --inetd -l 127.0.0.1:"${port}" -a tangd "${KEYS}" &
|
|
|
524513 |
+export PID=$!
|
|
|
524513 |
+sleep 0.25
|
|
|
524513 |
+
|
|
|
524513 |
+url="http://localhost:${port}"
|
|
|
524513 |
+adv="${TMP}/adv"
|
|
|
524513 |
+curl "${url}/adv" -o "${adv}"
|
|
|
524513 |
+
|
|
|
524513 |
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
|
|
|
524513 |
+
|
|
|
524513 |
+# LUKS2.
|
|
|
524513 |
+DEV="${TMP}/luks2-device"
|
|
|
524513 |
+new_device "luks2" "${DEV}"
|
|
|
524513 |
+
|
|
|
524513 |
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
|
|
|
524513 |
+ error "${TEST}: Bind should have succeeded."
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+#Now let's test the passphrase.
|
|
|
524513 |
+SLT=1
|
|
|
524513 |
+PASS=$(clevis luks pass -d "${DEV}" -s "${SLT}")
|
|
|
524513 |
+echo $PASS >&2
|
|
|
524513 |
+if ! cryptsetup luksOpen --test-passphrase ""${DEV} \
|
|
|
524513 |
+ --key-file <(clevis luks pass -d "${DEV}" -s "${SLT}"); then
|
|
|
524513 |
+ error "Passphrase obtained from clevis luks pass failed."
|
|
|
524513 |
+fi
|
|
|
524513 |
+
|
|
|
524513 |
+kill -9 "${PID}"
|
|
|
524513 |
+! wait "${PID}"
|
|
|
524513 |
+unset PID
|
|
|
524513 |
--
|
|
|
524513 |
2.18.1
|
|
|
524513 |
|