diff --git a/SOURCES/0010-existing-luks2-token-id.patch b/SOURCES/0010-existing-luks2-token-id.patch new file mode 100644 index 0000000..d257177 --- /dev/null +++ b/SOURCES/0010-existing-luks2-token-id.patch @@ -0,0 +1,385 @@ +--- clevis-18.ori/src/luks/clevis-luks-bind 2021-04-15 13:00:19.965065700 +0200 ++++ clevis-18/src/luks/clevis-luks-bind 2022-11-24 12:53:59.613676320 +0100 +@@ -25,7 +25,7 @@ + usage() { + exec >&2 + echo +- echo "Usage: clevis luks bind [-y] [-f] [-s SLT] [-k KEY] [-t TOKEN_ID] -d DEV PIN CFG" ++ echo "Usage: clevis luks bind [-y] [-f] [-s SLT] [-k KEY] [-t TOKEN_ID] [-e EXISTING_TOKEN_ID] -d DEV PIN CFG" + echo + echo "$SUMMARY": + echo +@@ -42,6 +42,8 @@ + echo " -k KEY Non-interactively read LUKS password from KEY file" + echo " -k - Non-interactively read LUKS password from standard input" + echo ++ echo " -e E_TKN_ID Existing LUKS token ID for existing passphrase; only available for LUKS2" ++ echo + exit 2 + } + +@@ -52,13 +54,14 @@ + + FRC= + YES= +-while getopts ":hfyd:s:k:t:" o; do ++while getopts ":hfyd:s:k:t:e:" o; do + case "$o" in + f) FRC='-f';; + d) DEV="$OPTARG";; + s) SLT="$OPTARG";; + k) KEY="$OPTARG";; + t) TOKEN_ID="$OPTARG";; ++ e) EXISTING_TOKEN_ID="$OPTARG";; + y) FRC='-f' + YES='-y';; + *) usage;; +@@ -99,11 +102,20 @@ + exit 1 + fi + ++if [ -n "${EXISTING_TOKEN_ID}" ] && ! clevis_luks_luks2_existing_token_id_supported; then ++ echo "Existing token ID not supported in this cryptsetup version" >&2 ++ exit 1 ++fi ++ + # Get the existing passphrase/keyfile. + existing_key= + keyfile= + case "${KEY}" in +-"") IFS= read -r -s -p "Enter existing LUKS password: " existing_key; echo >&2;; ++ "") ++ if [ -z "${EXISTING_TOKEN_ID}" ] ; then ++ IFS= read -r -s -p "Enter existing LUKS password: " existing_key; echo >&2 ++ fi ++ ;; + -) IFS= read -r -s -p "" existing_key ||: + if [ "${luks_type}" = "luks1" ] && ! luksmeta test -d "${DEV}" \ + && [ -z "${FRC}" ]; then +@@ -119,6 +131,13 @@ + ;; + esac + ++# Check if existing token id for keyring read is provided ++# If so, keyfile is not allowed ++if [ -n "${EXISTING_TOKEN_ID}" ] && [ -n "${keyfile}" ] ; then ++ echo "Cannot specify kernel keyring description together with key file" >&2 ++ exit 1 ++fi ++ + # If necessary, initialize the LUKS volume. + if [ "${luks_type}" = "luks1" ] && ! luksmeta test -d "${DEV}"; then + luksmeta init -d "${DEV}" ${FRC} +@@ -127,7 +146,7 @@ + if ! clevis_luks_do_bind "${DEV}" "${SLT}" "${TOKEN_ID}" \ + "${PIN}" "${CFG}" \ + "${YES}" "" \ +- "${existing_key}" "${keyfile}"; then ++ "${existing_key}" "${keyfile}" "${EXISTING_TOKEN_ID}"; then + echo "Error adding new binding to ${DEV}" >&2 + exit 1 + fi +--- clevis-18.ori/src/luks/clevis-luks-bind.1.adoc 2021-04-15 13:00:19.965065700 +0200 ++++ clevis-18/src/luks/clevis-luks-bind.1.adoc 2022-11-24 12:54:48.476829197 +0100 +@@ -9,7 +9,7 @@ + + == SYNOPSIS + +-*clevis luks bind* [-f] [-y] -d DEV [-t TKN_ID] [-s SLT] [-k KEY] PIN CFG ++*clevis luks bind* [-f] [-y] -d DEV [-t TKN_ID] [-s SLT] [-k KEY] [-e EXISTING_TOKEN_ID] PIN CFG + + == OVERVIEW + +@@ -54,6 +54,12 @@ + * *-k* - : + Non-interactively read LUKS password from standard input + ++* *-e* _E_TKN_ID_ : ++ LUKS token ID for existing passphrase; only available for LUKS2. ++ This parameter allows providing a configured token ID in LUKS2 ++ containing the existing passphrase for this device, so that ++ existing passphrase is not prompted by clevis ++ + == CAVEATS + + This command does not change the LUKS master key. This implies that if you +--- clevis-18.ori/src/luks/clevis-luks-common-functions.in 2022-11-24 12:46:09.130204312 +0100 ++++ clevis-18/src/luks/clevis-luks-common-functions.in 2022-11-24 13:01:57.087170193 +0100 +@@ -307,9 +307,10 @@ + local KEY="${2:-}" + local KEYFILE="${3:-}" + local SLT="${4:-}" ++ local EXISTING_TOKEN_ID="${5:-}" + + [ -z "${DEV}" ] && return 1 +- [ -z "${KEYFILE}" ] && [ -z "${KEY}" ] && return 1 ++ [ -z "${EXISTING_TOKEN_ID}" ] && [ -z "${KEYFILE}" ] && [ -z "${KEY}" ] && return 1 + + local extra_args + extra_args="$([ -n "${SLT}" ] && printf -- '--key-slot %s' "${SLT}")" +@@ -318,6 +319,11 @@ + ${extra_args} + return + fi ++ if [ -n "${EXISTING_TOKEN_ID}" ]; then ++ cryptsetup open --test-passphrase "${DEV}" --token-id "${EXISTING_TOKEN_ID}" \ ++ ${extra_args} ++ return ++ fi + + printf '%s' "${KEY}" | cryptsetup open --test-passphrase "${DEV}" \ + ${extra_args} +@@ -753,10 +759,11 @@ + local NEWKEY="${3}" + local KEY="${4}" + local KEYFILE="${5:-}" ++ local EXISTING_TOKEN_ID="${6:-}" + + [ -z "${DEV}" ] && return 1 + [ -z "${NEWKEY}" ] && return 1 +- [ -z "${KEY}" ] && [ -z "${KEYFILE}" ] && return 1 ++ [ -z "${EXISTING_TOKEN_ID}" ] && [ -z "${KEY}" ] && [ -z "${KEYFILE}" ] && return 1 + + local extra_args='' input + input="$(printf '%s\n%s' "${KEY}" "${NEWKEY}")" +@@ -764,6 +771,10 @@ + extra_args="$(printf -- '--key-file %s' "${KEYFILE}")" + input="$(printf '%s' "${NEWKEY}")" + fi ++ if [ -n "${EXISTING_TOKEN_ID}" ]; then ++ extra_args="$(printf -- '--token-id %s' "${EXISTING_TOKEN_ID}")" ++ input="$(printf '%s' "${NEWKEY}")" ++ fi + local pbkdf_args="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" + + printf '%s' "${input}" | cryptsetup luksAddKey --batch-mode \ +@@ -780,6 +791,7 @@ + local NEWKEY="${3}" + local KEY="${4}" + local KEYFILE="${5:-}" ++ local EXISTING_TOKEN_ID="${6:-}" + + [ -z "${DEV}" ] && return 1 + [ -z "${NEWKEY}" ] && return 1 +@@ -789,7 +801,7 @@ + local in_place + clevis_luks_check_valid_key_or_keyfile "${DEV}" \ + "${KEY}" "${KEYFILE}" \ +- "${SLT}" 2>/dev/null \ ++ "${SLT}" "${EXISTING_TOKEN_ID}" 2>/dev/null \ + && in_place=true + + local input extra_args= +@@ -798,6 +810,10 @@ + extra_args="$(printf -- '--key-file %s' "${KEYFILE}")" + input="$(printf '%s' "${NEWKEY}")" + fi ++ if [ -n "${EXISTING_TOKEN_ID}" ]; then ++ extra_args="$(printf -- '--token-id %s' "${EXISTING_TOKEN_ID}")" ++ input="$(printf '%s' "${NEWKEY}")" ++ fi + local pbkdf_args="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" + + if [ -n "${in_place}" ]; then +@@ -844,13 +860,13 @@ + [ -n "${OVERWRITE}" ] || return 1 + + clevis_luks_update_key "${DEV}" "${SLT}" \ +- "${NEWKEY}" "${KEY}" "${KEYFILE}" ++ "${NEWKEY}" "${KEY}" "${KEYFILE}" "${EXISTING_TOKEN_ID}" + return + fi + + # Add a new key. + clevis_luks_add_key "${DEV}" "${SLT}" \ +- "${NEWKEY}" "${KEY}" "${KEYFILE}" ++ "${NEWKEY}" "${KEY}" "${KEYFILE}" "${EXISTING_TOKEN_ID}" + } + + # clevis_luks_generate_key() generates a new key for use with clevis. +@@ -942,6 +958,7 @@ + local OVERWRITE="${7:-}" + local KEY="${8:-}" + local KEYFILE="${9:-}" ++ local EXISTING_TOKEN_ID="${10:-}" + + [ -z "${DEV}" ] && return 1 + [ -z "${PIN}" ] && return 1 +@@ -951,6 +968,8 @@ + if ! clevis_luks_check_valid_key_or_keyfile "${DEV}" \ + "${KEY}" \ + "${KEYFILE}" \ ++ "" \ ++ "${EXISTING_TOKEN_ID}" \ + && ! KEY="$(clevis_luks_get_existing_key "${DEV}" \ + "Enter existing LUKS password: " \ + "recover")"; then +@@ -995,7 +1014,7 @@ + + if ! clevis_luks_save_key_to_slot "${DEV}" "${SLT}" \ + "${newkey}" "${KEY}" "${KEYFILE}" \ +- "${OVERWRITE}"; then ++ "${OVERWRITE}" "${EXISTING_TOKEN_ID}"; then + echo "Unable to save/update key slot; operation cancelled" >&2 + clevis_luks_restore_dev "${CLEVIS_TMP_DIR}" || : + rm -rf "${CLEVIS_TMP_DIR}" +@@ -1016,12 +1035,19 @@ + } + + # clevis_luks_luks2_supported() indicates whether we support LUKS2 devices. +-# Suppor is determined at build time. ++# Support is determined at build time. + function clevis_luks_luks2_supported() { + # We require cryptsetup >= 2.0.4 to fully support LUKSv2. + return @OLD_CRYPTSETUP@ + } + ++# clevis_luks_luks2_existing_token_id_supported() indicates whether ++# cryptsetup allows token id for passphrase providing ++function clevis_luks_luks2_existing_token_id_supported() { ++ # We require cryptsetup >= 2.6.0 to fully support LUKSv2 addkey/open by token ID ++ return @OLD_CRYPTSETUP_EXISTING_TOKEN_ID@ ++} ++ + # clevis_luks_type() returns the LUKS type of a device, e.g. "luks1". + clevis_luks_type() { + local DEV="${1}" +--- clevis-18.ori/src/luks/meson.build 2021-04-15 13:00:19.965065700 +0200 ++++ clevis-18/src/luks/meson.build 2022-11-24 13:02:39.118301695 +0100 +@@ -14,6 +14,15 @@ + endif + endif + ++libcryptsetup_ext_token_id = dependency('libcryptsetup', version: '>=2.6.0', required: false) ++if libcryptsetup_ext_token_id.found() ++ luksmeta_data.set('OLD_CRYPTSETUP_EXISTING_TOKEN_ID', '0') ++ message('cryptsetup version supports existing token id') ++else ++ luksmeta_data.set('OLD_CRYPTSETUP_EXISTING_TOKEN_ID', '1') ++ warning('cryptsetup version does not support existing token id') ++endif ++ + clevis_luks_common_functions = configure_file( + input: 'clevis-luks-common-functions.in', + output: 'clevis-luks-common-functions', +--- clevis-18.ori/src/luks/tests/bind-luks2-ext-token 1970-01-01 01:00:00.000000000 +0100 ++++ clevis-18/src/luks/tests/bind-luks2-ext-token 2022-11-24 13:04:30.742650939 +0100 +@@ -0,0 +1,74 @@ ++#!/bin/bash -ex ++# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: ++# ++# Copyright (c) 2022 Red Hat, Inc. ++# Author: Sergio Arroutbi ++# ++# 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}" ++} ++ ++create_existing_token_id_from_keyring() { ++ local DEV="${1}" ++ local KEYDESC="${2}" ++ local TOKEN_ID="${3}" ++ local PASS="${4}" ++ if [[ -z "${DEV}" ]] || [[ -z "${KEYDESC}" ]] || [[ -z "${TOKEN_ID}" ]]; then ++ return 1 ++ fi ++ KEYRING_ID=$(keyctl add user "${KEYDESC}" "${PASS}" @s) ++ keyctl print "${KEYRING_ID}" 2>/dev/null 1>/dev/null ++ cryptsetup token add --token-id "${TOKEN_ID}" --key-description "${KEYDESC}" "${DEV}" ++} ++ ++if ! luks2_supported; then ++ skip_test "${TEST}: LUKS2 is not supported." ++fi ++ ++if ! luks2_existing_token_id_supported; then ++ skip_test "${TEST}: Existing token ID not supported" ++fi ++ ++trap 'on_exit' EXIT ++trap 'exit' ERR ++ ++TMP="$(mktemp -d)" ++ ++ADV="${TMP}/adv.jws" ++tang_create_adv "${TMP}" "${ADV}" ++CFG="$(printf '{"url":"foobar","adv":"%s"}' "$ADV")" ++ ++EXISTING_TOKEN_ID=5 ++KEYDESC="testkey" ++PASS="123exttokenid_" ++DEV="${TMP}/luks2-device-ext-token" ++new_device "luks2" "${DEV}" "${PASS}" ++ ++create_existing_token_id_from_keyring "${DEV}" "${KEYDESC}" "${EXISTING_TOKEN_ID}" "${PASS}" ++ ++if ! clevis luks bind -y -d "${DEV}" -e "${EXISTING_TOKEN_ID}" tang "${CFG}"; then ++ error "${TEST}: Binding expected to succeed with existing token id:${EXISTING_TOKEN_ID}" >&2 ++fi ++ ++KEYFILE="${TMP}/keyfile.txt" ++touch "${KEYFILE}" ++if clevis luks bind -y -d "${DEV}" -e "${EXISTING_TOKEN_ID}" -k "${KEYFILE}" tang "${CFG}"; then ++ error "${TEST}: Using existing token id and keyfile should dump an error" >&2 ++fi +--- clevis-18.ori/src/luks/tests/meson.build 2021-04-15 13:00:19.967066500 +0200 ++++ clevis-18/src/luks/tests/meson.build 2022-11-24 13:06:36.096043131 +0100 +@@ -5,6 +5,15 @@ + # given token slot. + cryptsetup = find_program('cryptsetup', required: true) + ++# Use keyctl to check an existing token id can be created from ++# kernel keyring password ++keyutils = find_program('keyctl', required: false) ++if keyutils.found() ++ message('keyutils installed') ++else ++ warning('keyutils not installed, unable to test existing token id binding') ++endif ++ + common_functions = configure_file(input: 'tests-common-functions.in', + output: 'tests-common-functions', + configuration: luksmeta_data, +@@ -69,6 +78,10 @@ + test('unbind-unbound-slot-luks2', find_program('unbind-unbound-slot-luks2'), env: env) + test('unbind-luks2', find_program('unbind-luks2'), env: env, timeout: 60) + ++ if keyutils.found() and luksmeta_data.get('OLD_CRYPTSETUP_EXISTING_TOKEN_ID') == '0' ++ test('bind-luks2-ext-token', find_program('bind-luks2-ext-token'), env: env, timeout: 60) ++ endif ++ + if jq.found() + test('list-recursive-luks2', find_program('list-recursive-luks2'), env: env, timeout: 60) + test('list-tang-luks2', find_program('list-tang-luks2'), env: env, timeout: 60) +--- clevis-18.ori/src/luks/tests/tests-common-functions.in 2021-04-15 13:00:19.967066500 +0200 ++++ clevis-18/src/luks/tests/tests-common-functions.in 2022-11-24 13:06:24.376006462 +0100 +@@ -36,6 +36,12 @@ + return @OLD_CRYPTSETUP@ + } + ++# We require cryptsetup >= 2.6.0 to fully support LUKSv2 addkey/open by token ID ++# Support is determined at build time. ++luks2_existing_token_id_supported() { ++ return @OLD_CRYPTSETUP_EXISTING_TOKEN_ID@ ++} ++ + # Creates a new LUKS1 or LUKS2 device to be used. + new_device() { + local LUKS="${1}" diff --git a/SOURCES/0011-ignore-empty-and-comment-lines-in-crypttab.patch b/SOURCES/0011-ignore-empty-and-comment-lines-in-crypttab.patch new file mode 100644 index 0000000..a92cb31 --- /dev/null +++ b/SOURCES/0011-ignore-empty-and-comment-lines-in-crypttab.patch @@ -0,0 +1,16 @@ +--- clevis-18.ori/src/luks/clevis-luks-common-functions.in 2023-01-12 11:00:00.927790464 +0100 ++++ clevis-18/src/luks/clevis-luks-common-functions.in 2023-01-12 11:05:53.528590215 +0100 +@@ -418,7 +418,12 @@ + clevis_devices= + + # Build list of devices to unlock. +- while read -r _ crypt_device _; do ++ while read -r _volname_ crypt_device _; do ++ # skip empty lines and lines which begin with the '#' char, per ++ # crypttab(5) ++ case $_volname_ in ++ ''|\#*) continue ;; ++ esac + if ! dev=$(clevis_map_device "${crypt_device}") \ + || [ -z "${dev}" ]; then + # Unable to get the device - maybe it's not available, e.g. a diff --git a/SOURCES/0012-luks-define-max-entropy-bits-for-pwmake.patch b/SOURCES/0012-luks-define-max-entropy-bits-for-pwmake.patch new file mode 100644 index 0000000..68dc097 --- /dev/null +++ b/SOURCES/0012-luks-define-max-entropy-bits-for-pwmake.patch @@ -0,0 +1,42 @@ +--- clevis-18.ori/src/clevis.1.adoc 2021-04-15 13:00:19.965065700 +0200 ++++ clevis-18/src/clevis.1.adoc 2023-01-13 12:08:31.162012856 +0100 +@@ -101,7 +101,7 @@ + + This command performs four steps: + +-1. Creates a new key with the same entropy as the LUKS master key. ++1. Creates a new key with the same entropy as the LUKS master key -- maximum entropy bits is 256. + 2. Encrypts the new key with Clevis. + 3. Stores the Clevis JWE in the LUKS header. + 4. Enables the new key for use with LUKS. +--- clevis-18.ori/src/luks/clevis-luks-bind.1.adoc 2023-01-13 12:02:52.005243591 +0100 ++++ clevis-18/src/luks/clevis-luks-bind.1.adoc 2023-01-13 12:08:05.873955501 +0100 +@@ -20,7 +20,7 @@ + + This command performs four steps: + +-1. Creates a new key with the same entropy as the LUKS master key. ++1. Creates a new key with the same entropy as the LUKS master key -- maximum entropy bits is 256. + 2. Encrypts the new key with Clevis. + 3. Stores the Clevis JWE in the LUKS header. + 4. Enables the new key for use with LUKS. +--- clevis-18.ori/src/luks/clevis-luks-common-functions.in 2023-01-13 12:02:52.005243591 +0100 ++++ clevis-18/src/luks/clevis-luks-common-functions.in 2023-01-13 12:06:29.233736316 +0100 +@@ -875,6 +875,7 @@ + [ -z "${DEV}" ] && return 1 + + local dump filter bits ++ local MAX_ENTROPY_BITS=256 # Maximum allowed by pwmake. + dump=$(cryptsetup luksDump "${DEV}") + if cryptsetup isLuks --type luks1 "${DEV}"; then + filter="$(echo "${dump}" | sed -rn 's|MK bits:[ \t]*([0-9]+)|\1|p')" +@@ -886,6 +887,9 @@ + fi + + bits="$(echo -n "${filter}" | sort -n | tail -n 1)" ++ if [ "${bits}" -gt "${MAX_ENTROPY_BITS}" ]; then ++ bits="${MAX_ENTROPY_BITS}" ++ fi + pwmake "${bits}" + } + diff --git a/SOURCES/0013-luks-edit-remove-unnecessary-redirection.patch b/SOURCES/0013-luks-edit-remove-unnecessary-redirection.patch new file mode 100644 index 0000000..ae1f82c --- /dev/null +++ b/SOURCES/0013-luks-edit-remove-unnecessary-redirection.patch @@ -0,0 +1,11 @@ +--- clevis-18.ori/src/luks/clevis-luks-edit 2021-04-15 13:00:19.965065700 +0200 ++++ clevis-18/src/luks/clevis-luks-edit 2023-01-16 10:24:18.555971552 +0100 +@@ -173,7 +173,7 @@ + + echo "Updating binding..." + if ! clevis_luks_do_bind "${DEV}" "${SLT}" "" "${pin}" "${new_cfg}" \ +- "-y" "overwrite" 2>/dev/null; then ++ "-y" "overwrite"; then + echo "Unable to update binding in ${DEV}:${SLT}. Operation cancelled." >&2 + exit 1 + fi diff --git a/SPECS/clevis.spec b/SPECS/clevis.spec index 6d7dd25..fbe33ba 100644 --- a/SPECS/clevis.spec +++ b/SPECS/clevis.spec @@ -1,6 +1,6 @@ Name: clevis Version: 18 -Release: 106%{?dist} +Release: 110%{?dist} Summary: Automated decryption framework License: GPLv3+ @@ -16,6 +16,10 @@ Patch0006: 0006-feat-rename-the-test-pin-to-null-pin.patch Patch0007: 0007-avoid-clevis-invalid-msg.patch Patch0008: 0008-Improve-boot-performance-by-removing-key-check.patch Patch0009: 0009-luks-enable-debugging-in-clevis-scripts-when-rd.debu.patch +Patch0010: 0010-existing-luks2-token-id.patch +Patch0011: 0011-ignore-empty-and-comment-lines-in-crypttab.patch +Patch0012: 0012-luks-define-max-entropy-bits-for-pwmake.patch +Patch0013: 0013-luks-edit-remove-unnecessary-redirection.patch BuildRequires: git-core BuildRequires: gcc @@ -196,6 +200,22 @@ systemctl preset %{name}-luks-askpass.path >/dev/null 2>&1 || : %attr(4755, root, root) %{_libexecdir}/%{name}-luks-udisks2 %changelog +* Wed Jan 25 2023 Sergio Arroutbi - 15-110 +- luks-edit: remove unnecessary 2>/dev/null + Resolves: rhbz#2159738 + +* Fri Jan 13 2023 Sergio Arroutbi - 15-109 +- luks: define max entropy bits for pwmake + Resolves: rhbz#2159735 + +* Thu Jan 12 2023 Sergio Arroutbi - 15-108 +- Ignore empty & comment lines in crypttab + Resolves: rhbz#2159728 + +* Tue Dec 13 2022 Sergio Arroutbi - 18-107 +- Add existing token id parameter + Resolves: rhbz#2126533 + * Tue Aug 02 2022 Sergio Correia - 18-106 - Enable debugging in clevis scripts when rd.debug is set Resolves: rhbz#2022420