diff --git a/0001-Backport-upstream-tests-and-fixes.patch b/0001-Backport-upstream-tests-and-fixes.patch new file mode 100644 index 0000000..5e56da3 --- /dev/null +++ b/0001-Backport-upstream-tests-and-fixes.patch @@ -0,0 +1,970 @@ +From c6d1b1a3128d29a2d13799cf869602d1afb02d57 Mon Sep 17 00:00:00 2001 +From: Sergio Correia +Date: Wed, 4 Dec 2019 18:11:00 -0300 +Subject: [PATCH] Backport upstream tests and fixes + +Commits backported: + +* Add tests for LUKS binding and unbinding +- https://github.com/latchset/clevis/pull/134/commits/f5d42cb3ba02ff8fcf39cc6c2751d2cd444f5a74 + +* Rework the logic for reading the existing key +- https://github.com/latchset/clevis/pull/141/commits/834eda9db62992fc235ecef41461502fd4084f6e + +* fix for different output from 'luksAddKey' command w/cryptsetup v2.0.2 ( +- https://github.com/latchset/clevis/commit/62bd6de0b8c36a238809546273ff08c3f3766564 + +* pins/tang: check that key derivation key is available +- https://github.com/latchset/clevis/pull/119/commits/c231352729223b08ade04e4e46c775bb934c9959 +--- + src/luks/clevis-luks-bind | 53 ++++++++--- + src/luks/meson.build | 5 +- + .../tests/bind-key-file-non-interactive-luks1 | 59 ++++++++++++ + src/luks/tests/bind-luks1 | 57 ++++++++++++ + src/luks/tests/bind-luks2 | 48 ++++++++++ + .../bind-pass-with-newline-keyfile-luks1 | 70 ++++++++++++++ + src/luks/tests/bind-pass-with-newline-luks1 | 67 +++++++++++++ + src/luks/tests/bind-wrong-pass-luks1 | 56 +++++++++++ + src/luks/tests/bind-wrong-pass-luks2 | 47 ++++++++++ + src/luks/tests/meson.build | 27 ++++++ + src/luks/tests/tests-common-functions | 93 +++++++++++++++++++ + src/luks/tests/unbind-luks1 | 74 +++++++++++++++ + src/luks/tests/unbind-luks2 | 51 ++++++++++ + src/luks/tests/unbind-unbound-slot-luks1 | 40 ++++++++ + src/luks/tests/unbind-unbound-slot-luks2 | 41 ++++++++ + src/pins/tang/clevis-encrypt-tang | 6 +- + 16 files changed, 780 insertions(+), 14 deletions(-) + create mode 100755 src/luks/tests/bind-key-file-non-interactive-luks1 + create mode 100755 src/luks/tests/bind-luks1 + create mode 100755 src/luks/tests/bind-luks2 + create mode 100755 src/luks/tests/bind-pass-with-newline-keyfile-luks1 + create mode 100755 src/luks/tests/bind-pass-with-newline-luks1 + create mode 100755 src/luks/tests/bind-wrong-pass-luks1 + create mode 100755 src/luks/tests/bind-wrong-pass-luks2 + create mode 100644 src/luks/tests/meson.build + create mode 100755 src/luks/tests/tests-common-functions + create mode 100755 src/luks/tests/unbind-luks1 + create mode 100755 src/luks/tests/unbind-luks2 + create mode 100755 src/luks/tests/unbind-unbound-slot-luks1 + create mode 100755 src/luks/tests/unbind-unbound-slot-luks2 + +diff --git a/src/luks/clevis-luks-bind b/src/luks/clevis-luks-bind +index 7aae2ea..6edfccd 100755 +--- a/src/luks/clevis-luks-bind ++++ b/src/luks/clevis-luks-bind +@@ -107,26 +107,55 @@ if cryptsetup isLuks --type luks1 "$DEV" && ! luksmeta test -d "$DEV"; then + luksmeta init -d "$DEV" $FRC + fi + +-# Get the old key ++# Get the existing key. + case "$KEY" in +-"") read -s -p "Enter existing LUKS password: " old; echo;; +- -) old=`/bin/cat`;; +- *) old=`/bin/cat "$KEY"`;; ++"") read -r -s -p "Enter existing LUKS password: " existing_key; echo;; ++ -) existing_key="$(/bin/cat)";; ++ *) ! IFS= read -rd '' existing_key < "$KEY";; + esac + +-# Add the new key ++ ++#Add the new key + if [ -n "$SLT" ]; then +- if ! echo -e "$old\n$key" | cryptsetup luksAddKey --key-slot $SLT $DEV; then +- echo "Error while adding new key to LUKS header!" >&2 +- exit 1 ++ cryptsetup luksAddKey --key-slot "$SLT" --key-file \ ++ <(echo -n "$existing_key") "$DEV" ++else ++ if cryptsetup isLuks --type luks2 "${DEV}"; then ++ readarray -t usedSlotsBeforeAddKey < <(cryptsetup luksDump "${DEV}" \ ++ | sed -rn 's|^\s+([0-9]+): luks2$|\1|p') ++ else ++ readarray -t usedSlotsBeforeAddKey < <(cryptsetup luksDump "${DEV}" \ ++ | sed -rn 's|^Key Slot ([0-7]): ENABLED$|\1|p') + fi +-elif ! SLT=`echo -e "$old\n$key" \ +- | cryptsetup luksAddKey -v $DEV \ +- | sed -rn 's|^Key slot ([0-9]+) created\.$|\1|p'`; then ++ cryptsetup luksAddKey --key-file <(echo -n "${existing_key}") "$DEV" ++fi < <(echo -n "${key}") ++if [ $? -ne 0 ]; then + echo "Error while adding new key to LUKS header!" >&2 + exit 1 + fi + ++#Determine slot used by new key if a desired slot was not specified ++if [ -z "$SLT" ]; then ++ if cryptsetup isLuks --type luks2 "${DEV}"; then ++ readarray -t usedSlotsAfterAddKey < <(cryptsetup luksDump "${DEV}" \ ++ | sed -rn 's|^\s+([0-9]+): luks2$|\1|p') ++ else ++ readarray -t usedSlotsAfterAddKey < <(cryptsetup luksDump "${DEV}" \ ++ | sed -rn 's|^Key Slot ([0-7]): ENABLED$|\1|p') ++ fi ++ for i in "${usedSlotsAfterAddKey[@]}"; do ++ if [[ ! " ${usedSlotsBeforeAddKey[@]} " =~ " ${i} " ]]; then ++ SLT=$i ++ break ++ fi ++ done ++fi ++ ++if [ -z "$SLT" ]; then ++ echo "Error while adding new key to LUKS header! Key slot is undefined." >&2 ++ exit 1 ++fi ++ + if cryptsetup isLuks --type luks1 "$DEV"; then + if ! echo -n $jwe | luksmeta save -d "$DEV" -u "$UUID" -s $SLT 2>/dev/null; then + echo "Error while saving Clevis metadata in LUKSMeta!" >&2 +@@ -142,4 +171,4 @@ else + cryptsetup luksRemoveKey "$DEV" <<<"$key" + exit 1 + fi +-fi +\ No newline at end of file ++fi +diff --git a/src/luks/meson.build b/src/luks/meson.build +index 1f64ab0..2935c3f 100644 +--- a/src/luks/meson.build ++++ b/src/luks/meson.build +@@ -18,4 +18,7 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found() + mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlockers.7') + else + warning('Will not install LUKS support due to missing dependencies!') +-endif +\ No newline at end of file ++endif ++ ++# Tests. ++subdir('tests') +diff --git a/src/luks/tests/bind-key-file-non-interactive-luks1 b/src/luks/tests/bind-key-file-non-interactive-luks1 +new file mode 100755 +index 0000000..f5b5d03 +--- /dev/null ++++ b/src/luks/tests/bind-key-file-non-interactive-luks1 +@@ -0,0 +1,59 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST="${0}" ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++UUID="cb6e8904-81ff-40da-a84a-07ab9ab5715e" ++KEYFILE="${TMP}/key" ++PASS=$(openssl rand -hex 8) ++echo -n "${PASS}" > "${KEYFILE}" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++new_device_keyfile "luks1" "${DEV}" "${KEYFILE}" ++if ! clevis luks bind -f -k "${KEYFILE}" -d "${DEV}" tang "${CFG}"; then ++ error "${TEST}: Binding is expected to succeed when given a correct (${KEYFILE})." >&2 ++fi ++ ++SLT=1 ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "active" ]; then ++ error "${TEST}: state (${state}) is expected to be 'active'." >&2 ++fi ++ ++if [ "${uuid}" != "${UUID}" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be '${UUID}'." >&2 ++fi +diff --git a/src/luks/tests/bind-luks1 b/src/luks/tests/bind-luks1 +new file mode 100755 +index 0000000..281a328 +--- /dev/null ++++ b/src/luks/tests/bind-luks1 +@@ -0,0 +1,57 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++UUID="cb6e8904-81ff-40da-a84a-07ab9ab5715e" ++new_device "luks1" "${DEV}" ++ ++if ! clevis luks bind -f -d "${DEV}" tang "${CFG}" <<< "${DEFAULT_PASS}"; then ++ error "${TEST}: Binding is expected to succeed when given a correct (${DEFAULT_PASS}) password." >&2 ++fi ++ ++SLT=1 ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "active" ]; then ++ error "${TEST}: state (${state}) is expected to be 'active'." >&2 ++fi ++ ++if [ "${uuid}" != "${UUID}" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be '${UUID}'." >&2 ++fi +diff --git a/src/luks/tests/bind-luks2 b/src/luks/tests/bind-luks2 +new file mode 100755 +index 0000000..11f988c +--- /dev/null ++++ b/src/luks/tests/bind-luks2 +@@ -0,0 +1,48 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++if ! luks2_supported; then ++ error "{TEST}: LUKS2 is not supported." ++fi ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS2. ++ ++DEV="${TMP}/luks2-device" ++new_device "luks2" "${DEV}" ++ ++if ! clevis luks bind -d "${DEV}" tang "${CFG}" <<< "${DEFAULT_PASS}"; then ++ error "${TEST}: Binding is expected to succeed when given a correct (${DEFAULT_PASS}) password." >&2 ++fi +diff --git a/src/luks/tests/bind-pass-with-newline-keyfile-luks1 b/src/luks/tests/bind-pass-with-newline-keyfile-luks1 +new file mode 100755 +index 0000000..bce584e +--- /dev/null ++++ b/src/luks/tests/bind-pass-with-newline-keyfile-luks1 +@@ -0,0 +1,70 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST="${0}" ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++UUID="cb6e8904-81ff-40da-a84a-07ab9ab5715e" ++ ++# Using newlines and special chars in the passphrase. ++PASS="foo ++ ++bar ++ ++\\\&#@@&@*!)( ++ ++$$$ ++" ++ ++KEYFILE="${TMP}/key" ++echo -n "${PASS}" > "${KEYFILE}" ++ ++new_device_keyfile "luks1" "${DEV}" "${KEYFILE}" ++if ! clevis luks bind -f -k "${KEYFILE}" -d "${DEV}" tang "${CFG}"; then ++ error "${TEST}: Binding is expected to succeed when given a correct (${KEYFILE}) password." >&2 ++fi ++ ++SLT=1 ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "active" ]; then ++ error "${TEST}: state (${state}) is expected to be 'active'." >&2 ++fi ++ ++if [ "${uuid}" != "${UUID}" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be '${UUID}'." >&2 ++fi +diff --git a/src/luks/tests/bind-pass-with-newline-luks1 b/src/luks/tests/bind-pass-with-newline-luks1 +new file mode 100755 +index 0000000..89de082 +--- /dev/null ++++ b/src/luks/tests/bind-pass-with-newline-luks1 +@@ -0,0 +1,67 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST="${0}" ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++UUID="cb6e8904-81ff-40da-a84a-07ab9ab5715e" ++ ++# Using newlines and special chars in the passphrase. ++PASS="foo ++ ++bar ++ ++\\\&#@@&@*!)( ++ ++$$$ ++" ++new_device "luks1" "${DEV}" "${PASS}" ++ ++if ! clevis luks bind -f -d "${DEV}" tang "${CFG}" <<< "${PASS}"; then ++ error "${TEST}: Binding is expected to succeed when given a correct (${PASS}) password." >&2 ++fi ++ ++SLT=1 ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "active" ]; then ++ error "${TEST}: state (${state}) is expected to be 'active'." >&2 ++fi ++ ++if [ "${uuid}" != "${UUID}" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be '${UUID}'." >&2 ++fi +diff --git a/src/luks/tests/bind-wrong-pass-luks1 b/src/luks/tests/bind-wrong-pass-luks1 +new file mode 100755 +index 0000000..a15945e +--- /dev/null ++++ b/src/luks/tests/bind-wrong-pass-luks1 +@@ -0,0 +1,56 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++new_device "luks1" "${DEV}" ++ ++if clevis luks bind -f -d "${DEV}" tang "${CFG}" <<< "wrong-passphrase"; then ++ error "${TEST}: Binding is expected to fail when given a wrong password." >&2 ++fi ++ ++SLT=1 ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "inactive" ]; then ++ error "${TEST}: state (${state}) is expected to be 'inactive'." >&2 ++fi ++ ++if [ "${uuid}" != "empty" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be 'empty'." >&2 ++fi +diff --git a/src/luks/tests/bind-wrong-pass-luks2 b/src/luks/tests/bind-wrong-pass-luks2 +new file mode 100755 +index 0000000..cbbb095 +--- /dev/null ++++ b/src/luks/tests/bind-wrong-pass-luks2 +@@ -0,0 +1,47 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++if ! luks2_supported; then ++ error "{TEST}: LUKS2 is not supported." ++fi ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS2. ++DEV="${TMP}/luks2-device" ++new_device "luks2" "${DEV}" ++ ++if clevis luks bind -d "${DEV}" tang "${CFG}" <<< "wrong-passphrase"; then ++ error "${TEST}: Binding is expected to fail when given a wrong password." >&2 ++fi +diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build +new file mode 100644 +index 0000000..85b8a99 +--- /dev/null ++++ b/src/luks/tests/meson.build +@@ -0,0 +1,27 @@ ++env = environment() ++env.prepend('PATH', ++ join_paths(meson.source_root(), 'src'), ++ join_paths(meson.source_root(), 'src', 'luks'), ++ join_paths(meson.source_root(), 'src', 'pins', 'tang'), ++ join_paths(meson.source_root(), 'src', 'pins', 'tpm2'), ++ meson.current_source_dir(), ++ meson.current_build_dir(), ++ join_paths(meson.build_root(), 'src'), ++ join_paths(meson.build_root(), 'src', 'luks'), ++ separator: ':' ++) ++ ++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) ++test('unbind-luks1', find_program('unbind-luks1'), env: env) ++test('bind-key-file-non-interactive', find_program('bind-key-file-non-interactive-luks1'), env: env) ++test('bind-pass-with-newline', find_program('bind-pass-with-newline-luks1'), env: env) ++test('bind-pass-with-newline-keyfile', find_program('bind-pass-with-newline-keyfile-luks1'), env: env) ++ ++# LUKS2 tests go here. ++# Binding LUKS2 takes longer, so timeout is increased for a few tests. ++test('bind-wrong-pass-luks2', find_program('bind-wrong-pass-luks2'), env: env) ++test('bind-luks2', find_program('bind-luks2'), env: env, timeout: 60) ++test('unbind-unbound-slot-luks2', find_program('unbind-unbound-slot-luks2'), env: env) ++test('unbind-luks2', find_program('unbind-luks2'), env: env, timeout: 60) +diff --git a/src/luks/tests/tests-common-functions b/src/luks/tests/tests-common-functions +new file mode 100755 +index 0000000..4befaa9 +--- /dev/null ++++ b/src/luks/tests/tests-common-functions +@@ -0,0 +1,93 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++error() { ++ echo "${1}" >&2 ++ exit 1 ++} ++ ++# We require cryptsetup >= 2.0.4 to fully support LUKSv2. ++# Support is determined at build time. ++luks2_supported() { ++ return 0 ++} ++ ++# Creates a tang adv to be used in the test. ++create_tang_adv() { ++ local adv="${1}" ++ local SIG="${TMP}/sig.jwk" ++ jose jwk gen -i '{"alg":"ES512"}' > "${SIG}" ++ ++ local EXC="${TMP}/exc.jwk" ++ jose jwk gen -i '{"alg":"ECMR"}' > "${EXC}" ++ ++ local TEMPLATE='{"protected":{"cty":"jwk-set+json"}}' ++ jose jwk pub -s -i "${SIG}" -i "${EXC}" \ ++ | jose jws sig -I- -s "${TEMPLATE}" -k "${SIG}" -o "${adv}" ++} ++ ++ ++# Creates a new LUKS1 or LUKS2 device to be used. ++new_device() { ++ local LUKS="${1}" ++ local DEV="${2}" ++ local PASS="${3}" ++ ++ # Using a default password, if none has been provided. ++ if [ -z "${PASS}" ]; then ++ PASS="${DEFAULT_PASS}" ++ fi ++ ++ local DEV_CACHED="${TMP}/${LUKS}.cached" ++ ++ # Let's reuse an existing device, if there is one. ++ if [ -f "${DEV_CACHED}" ]; then ++ echo "Reusing cached ${LUKS} device..." ++ cp -f "${DEV_CACHED}" "${DEV}" ++ return 0 ++ fi ++ ++ fallocate -l16M "${DEV}" ++ local extra_options= ++ if [ "${LUKS}" = "luks2" ]; then ++ extra_options="--pbkdf pbkdf2" ++ fi ++ if ! cryptsetup luksFormat --type "${LUKS}" --batch-mode --force-password "${DEV}" <<< "${PASS}"; then ++ cryptsetup luksFormat --type "${LUKS}" --batch-mode --force-password "${DEV}" --debug 2>&1 <<< "${PASS}" ++ fi ++ # Caching the just-formatted device for possible reuse. ++ cp -f "${DEV}" "${DEV_CACHED}" ++} ++ ++# Creates a new LUKS1 or LUKS2 device to be used, using a keyfile. ++new_device_keyfile() { ++ local LUKS="${1}" ++ local DEV="${2}" ++ local KEYFILE="${3}" ++ ++ if [[ -z "${KEYFILE}" ]] || [[ ! -f "${KEYFILE}" ]]; then ++ error "Invalid keyfile (${KEYFILE})." ++ fi ++ ++ fallocate -l16M "${DEV}" ++ cryptsetup luksFormat --type "${LUKS}" --batch-mode "${DEV}" "${KEYFILE}" ++} ++ ++export DEFAULT_PASS='just-some-test-password-here' +diff --git a/src/luks/tests/unbind-luks1 b/src/luks/tests/unbind-luks1 +new file mode 100755 +index 0000000..56cf8c0 +--- /dev/null ++++ b/src/luks/tests/unbind-luks1 +@@ -0,0 +1,74 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++UUID="cb6e8904-81ff-40da-a84a-07ab9ab5715e" ++new_device "luks1" "${DEV}" ++ ++# Bind, initially. ++if ! clevis luks bind -f -d "${DEV}" tang "${CFG}" <<< "${DEFAULT_PASS}"; then ++ error "${TEST}: Binding is expected to succeed when given a correct (${DEFAULT_PASS}) password." >&2 ++fi ++ ++SLT=1 ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "active" ]; then ++ error "${TEST}: state (${state}) is expected to be 'active'." >&2 ++fi ++ ++if [ "${uuid}" != "${UUID}" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be '${UUID}'." >&2 ++fi ++ ++# Now unbind. ++if ! clevis luks unbind -f -d "${DEV}" -s "${SLT}"; then ++ error "${TEST}: Unbind is expected to succeed for device ${DEV} and slot ${SLT}" >&2 ++fi ++ ++if ! read -r _ state uuid < <(luksmeta show -d "${DEV}" | grep "^${SLT} *"); then ++ error "${TEST}: Error reading LUKSmeta info for slot ${SLT} of ${DEV}." >&2 ++fi ++ ++if [ "${state}" != "inactive" ]; then ++ error "${TEST}: state (${state}) is expected to be 'inactive'." >&2 ++fi ++ ++if [ "${uuid}" != "empty" ]; then ++ error "${TEST}: UUID ($uuid) is expected to be 'empty'." >&2 ++fi +diff --git a/src/luks/tests/unbind-luks2 b/src/luks/tests/unbind-luks2 +new file mode 100755 +index 0000000..82871be +--- /dev/null ++++ b/src/luks/tests/unbind-luks2 +@@ -0,0 +1,51 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++if ! luks2_supported; then ++ error "{TEST}: LUKS2 is not supported." ++fi ++ ++TMP="$(mktemp -d)" ++ADV="${TMP}/adv.jws" ++create_tang_adv "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++# LUKS2. ++DEV="${TMP}/luks2-device" ++new_device "luks2" "${DEV}" ++# Binding. ++if ! clevis luks bind -d "${DEV}" tang "${CFG}" <<< "${DEFAULT_PASS}"; then ++ error "${TEST}: Binding is expected to succeed." >&2 ++fi ++ ++SLT=1 ++if ! clevis luks unbind -f -d "${DEV}" -s "${SLT}"; then ++ error "${TEST}: Unbind is expected to succeed for device ${DEV} and slot ${SLT}" >&2 ++fi +diff --git a/src/luks/tests/unbind-unbound-slot-luks1 b/src/luks/tests/unbind-unbound-slot-luks1 +new file mode 100755 +index 0000000..e562a36 +--- /dev/null ++++ b/src/luks/tests/unbind-unbound-slot-luks1 +@@ -0,0 +1,40 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++# LUKS1. ++DEV="${TMP}/luks1-device" ++new_device "luks1" "${DEV}" ++ ++SLT=2 ++if clevis luks unbind -d "${DEV}" -s "${SLT}"; then ++ error "${TEST}: Unbind is expected to fail for device ${DEV} and slot ${SLT}" >&2 ++fi +diff --git a/src/luks/tests/unbind-unbound-slot-luks2 b/src/luks/tests/unbind-unbound-slot-luks2 +new file mode 100755 +index 0000000..6a2aca5 +--- /dev/null ++++ b/src/luks/tests/unbind-unbound-slot-luks2 +@@ -0,0 +1,41 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2019 Red Hat, Inc. ++# Author: Sergio Correia ++# ++# 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 . ++# ++ ++TEST=$(basename "${0}") ++. tests-common-functions ++ ++on_exit() { ++ [ -d "${TMP}" ] && rm -rf "${TMP}" ++} ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++if ! luks2_supported; then ++ error "{TEST}: LUKS2 is not supported." ++fi ++ ++TMP="$(mktemp -d)" ++ ++DEV="${TMP}/luks2-device" ++new_device "luks2" "${DEV}" ++if clevis luks unbind -d "${DEV}" -s "${SLT}"; then ++ error "${TEST}: Unbind is expected to fail for device ${DEV} and slot ${SLT}" >&2 ++fi +diff --git a/src/pins/tang/clevis-encrypt-tang b/src/pins/tang/clevis-encrypt-tang +index e65a7d1..5461b45 100755 +--- a/src/pins/tang/clevis-encrypt-tang ++++ b/src/pins/tang/clevis-encrypt-tang +@@ -114,7 +114,11 @@ elif [ "$thp" != "any" ] && \ + fi + + ### Perform encryption +-enc=`jose jwk use -i- -r -u deriveKey -o- <<< "$jwks"` ++if ! enc="$(jose jwk use -i- -r -u deriveKey -o- <<< "$jwks")"; then ++ echo "Key derivation key not available!" >&2 ++ exit 1 ++fi ++ + jose fmt -j "$enc" -Og keys -A || enc="{\"keys\":[$enc]}" + + for jwk in `jose fmt -j- -Og keys -Af- <<< "$enc"`; do +-- +2.23.0 + diff --git a/clevis.spec b/clevis.spec index c5b5a55..9ac49b5 100644 --- a/clevis.spec +++ b/clevis.spec @@ -3,7 +3,7 @@ Name: clevis Version: 11 -Release: 8%{?dist} +Release: 9%{?dist} Summary: Automated decryption framework License: GPLv3+ @@ -18,6 +18,8 @@ Patch2: Add-device-TCTI-library-to-the-initramfs.patch Patch4: clevis-encrypt-tpm2-fix-TPM-object-attributes.patch Patch5: clevis-pin-tpm2-module-setup.sh-test-for-required-bi.patch Patch6: pins-tpm2-add-support-for-tpm2-tools-4.X.patch +# Backport of some fixes and also adding tests in the build. +Patch7: 0001-Backport-upstream-tests-and-fixes.patch BuildRequires: gcc BuildRequires: meson @@ -38,6 +40,9 @@ BuildRequires: systemd BuildRequires: dracut BuildRequires: tang >= 6 BuildRequires: curl +BuildRequires: cracklib-dicts +BuildRequires: luksmeta +BuildRequires: openssl Requires: tpm2-tools >= 3.0.0 Requires: coreutils @@ -165,6 +170,12 @@ exit 0 %attr(4755, root, root) %{_libexecdir}/%{name}-luks-udisks2 %changelog +* Wed Dec 04 2019 Sergio Correia - 11-9 +- Backport of upstream patches and the following fixes: + - Rework the logic for reading the existing key + - fix for different output from 'luksAddKey' command w/cryptsetup v2.0.2 ( + - pins/tang: check that key derivation key is available + * Wed Oct 30 2019 Peter Robinson 11-8 - Drop need network patch