From 70d3da5ce8d68e8ff258122592670eb70da0c839 Mon Sep 17 00:00:00 2001 From: Sergio Correia Date: Wed, 16 Oct 2019 09:14:58 -0300 Subject: [PATCH 2/2] Add clevis luks report/regen --- src/luks/clevis-luks-common-functions | 143 ++++++++++++++++++++ src/luks/clevis-luks-regen | 186 ++++++++++++++++++++++++++ src/luks/clevis-luks-regen.1.adoc | 36 +++++ src/luks/clevis-luks-report | 95 +++++++++++++ src/luks/clevis-luks-report-compare | 71 ++++++++++ src/luks/clevis-luks-report-decode | 59 ++++++++ src/luks/clevis-luks-report-sss | 53 ++++++++ src/luks/clevis-luks-report-tang | 67 ++++++++++ src/luks/clevis-luks-report.1.adoc | 41 ++++++ src/luks/meson.build | 12 ++ 10 files changed, 763 insertions(+) create mode 100644 src/luks/clevis-luks-common-functions create mode 100755 src/luks/clevis-luks-regen create mode 100644 src/luks/clevis-luks-regen.1.adoc create mode 100755 src/luks/clevis-luks-report create mode 100755 src/luks/clevis-luks-report-compare create mode 100755 src/luks/clevis-luks-report-decode create mode 100755 src/luks/clevis-luks-report-sss create mode 100755 src/luks/clevis-luks-report-tang create mode 100644 src/luks/clevis-luks-report.1.adoc diff --git a/src/luks/clevis-luks-common-functions b/src/luks/clevis-luks-common-functions new file mode 100644 index 0000000..d676253 --- /dev/null +++ b/src/luks/clevis-luks-common-functions @@ -0,0 +1,143 @@ +#!/bin/bash -e +# 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 . +# + +# valid_slot() will check whether a given slot is possibly valid, i.e., if it +# is a numeric value within the specified range. +valid_slot() { + local SLT="${1}" + local MAX_SLOTS="${2}" + case "${SLT}" in + ''|*[!0-9]*) + return 1 + ;; + *) + # We got an integer, now let's make sure it is within the + # supported range. + if [ "${SLT}" -ge "${MAX_SLOTS}" ]; then + return 1 + fi + ;; + esac +} + +# clevis_luks_read_slot() will read a particular slot of a given device, which +# should be either LUKS1 or LUKS2. Returns 1 in case of failure; 0 in case of +# success. +clevis_luks_read_slot() { + local DEV="${1}" + local SLT="${2}" + + if [ -z "${DEV}" ] || [ -z "${SLT}" ]; then + echo "Need both a device and a slot as arguments." >&2 + return 1 + fi + + local DATA_CODED='' + local MAX_LUKS1_SLOTS=8 + local MAX_LUKS2_SLOTS=32 + if cryptsetup isLuks --type luks1 "${DEV}"; then + if ! valid_slot "${SLT}" "${MAX_LUKS1_SLOTS}"; then + echo "Please, provide a valid key slot number; 0-7 for LUKS1" >&2 + return 1 + fi + + if ! luksmeta test -d "${DEV}"; then + echo "The ${DEV} device is not valid!" >&2 + return 1 + fi + + local uuid + # Pattern from luksmeta: active slot uuid. + read -r _ _ uuid <<< "$(luksmeta show -d "${DEV}" | grep "^${SLT} *")" + + if [ "${uuid}" = "empty" ]; then + echo "The LUKSMeta slot ${SLT} on device ${DEV} is already empty." >&2 + return 1 + fi + + if ! DATA_CODED="$(luksmeta load -d "${DEV}" -s "${SLT}")"; then + echo "Cannot load data from ${DEV} slot:${SLT}!" >&2 + return 1 + fi + elif cryptsetup isLuks --type luks2 "${DEV}"; then + if ! valid_slot "${SLT}" "${MAX_LUKS2_SLOTS}"; then + echo "Please, provide a valid key slot number; 0-31 for LUKS2" >&2 + return 1 + fi + + local token_id + token_id=$(cryptsetup luksDump "${DEV}" \ + | grep -E -B1 "^\s+Keyslot:\s+${SLT}$" \ + | head -n 1 | sed -rn 's|^\s+([0-9]+): clevis|\1|p') + if [ -z "${token_id}" ]; then + echo "Cannot load data from ${DEV} slot:${SLT}. No token found!" >&2 + return 1 + fi + + local token + token=$(cryptsetup token export --token-id "${token_id}" "${DEV}") + DATA_CODED=$(jose fmt -j- -Og jwe -o- <<< "${token}" \ + | jose jwe fmt -i- -c) + + if [ -z "${DATA_CODED}" ]; then + echo "Cannot load data from ${DEV} slot:${SLT}!" >&2 + return 1 + fi + else + echo "${DEV} is not a supported LUKS device!" >&2 + return 1 + fi + echo "${DATA_CODED}" +} + +# Generate a key with the same entropy as the LUKS Master key of a given +# device. +generate_key() { + local DEV="${1}" + + if [ -z "${DEV}" ]; then + echo "Please, specify a device." >&2 + return 1 + fi + + local dump + local filter + dump=$(cryptsetup luksDump "${DEV}") + if cryptsetup isLuks --type luks1 "${DEV}"; then + filter=$(sed -rn 's|MK bits:[ \t]*([0-9]+)|\1|p' <<< "${dump}") + elif cryptsetup isLuks --type luks2 "${DEV}"; then + filter=$(sed -rn 's|^\s+Key:\s+([0-9]+) bits\s*$|\1|p' <<< "${dump}") + else + echo "${DEV} is not a supported LUKS device!" >&2 + return 1 + fi + local bits + bits=$(sort -n <<< "${filter}" | tail -n 1) + pwmake "${bits}" +} + +findexe() { + while read -r -d: path; do + [ -f "${path}/${1}" ] && [ -x "${path}/${1}" ] && \ + echo "${path}/${1}" && return 0 + done <<< "${PATH}:" + return 1 +} + diff --git a/src/luks/clevis-luks-regen b/src/luks/clevis-luks-regen new file mode 100755 index 0000000..9535ba3 --- /dev/null +++ b/src/luks/clevis-luks-regen @@ -0,0 +1,186 @@ +#!/usr/bin/env bash +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2018 Red Hat, Inc. +# Author: Radovan Sroka +# +# 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 . +# + +. clevis-luks-common-functions + +SUMMARY="Regenerate LUKS metadata" + +if [ "$1" == "--summary" ]; then + echo "$SUMMARY" + exit 0 +fi + +function usage_and_exit () { + echo >&2 + echo "Usage: clevis luks regen -d DEV -s SLOT" >&2 + echo >&2 + echo "$SUMMARY" >&2 + echo >&2 + exit "$1" +} + +if [ "$#" -ne "4" ]; then + usage_and_exit 1 +fi + +while getopts "hd:s:" o; do + case "$o" in + d) DEV="$OPTARG";; + h) usage_and_exit 0;; + s) SLT="$OPTARG";; + *) usage_and_exit 1;; + esac +done + +function decode_luks_header () { + if DATA_CODED="$(jose jwe fmt -i- <<< "$1")"; then + DATA_CODED="$(jose fmt -j- -g protected -u- <<< "$DATA_CODED")" + DATA_DECODED="$(jose b64 dec -i- <<< "$DATA_CODED")" + else + echo "Error decoding JWE protected header!" >&2 + exit 1 + fi + + echo "$DATA_DECODED" +} + +function generate_cfg () { + echo -n "{" + DATA="$(decode_luks_header "$1")" + + if ! P="$(jose fmt -j- -g clevis -g pin -u- <<< "$DATA")" || [ -z "$P" ]; then + echo "Pin wasn't found in LUKS metadata!" >&2 + exit 1 + fi + + if ! CONTENT="$(jose fmt -j- -g clevis -g "$P" -o- <<< "$DATA")" || [ -z "$CONTENT" ]; then + echo "Content was not found!" >&2 + fi + + # echo -n "\"$P\": [" + + if [ "$P" = "tang" ] || [ "$P" = "http" ]; then + URL="$(jose fmt -j- -g url -u- <<< "$CONTENT")" + echo -n "\"url\":\"$URL\"" + elif [ "$P" = "sss" ]; then + THRESHOLD="$(jose fmt -j- -g t -o- <<< "$CONTENT")" + if [ -n "$THRESHOLD" ]; then + echo -n "\"t\":$THRESHOLD," + fi + + echo -n "\"pins\":{" + + CNT=0 + PREV="" + while ITEM="$(jose fmt -j- -g jwe -g"$CNT" -u- <<< "$CONTENT")"; do + if [ -z "$ITEM" ]; then + CNT=$(( CNT + 1 )) + continue # in some cases it can be empty string + fi + + DD="$(decode_luks_header "$ITEM")" + + if ! PP="$(jose fmt -j- -g clevis -g pin -u- <<< "$DD")" || [ -z "$PP" ]; then + echo "Pin wasn't found in LUKS metadata!" >&2 + exit 1 + fi + + if [ "$CNT" -eq 0 ]; then + PREV="$PP" + echo -n "\"$PP\":[" + echo -n "$(generate_cfg "$ITEM")" + else + if ! [ "$PREV" = "$PP" ]; then + echo -n "],\"$PP\":[" + echo -n "$(generate_cfg "$ITEM")" + else + echo -n ",$(generate_cfg "$ITEM")" + fi + fi + + PREV="$PP" + CNT=$(( CNT + 1 )) + done + + echo -n "]}" + + else + echo "Unknown pin $P!" >&2 + exit 1 + fi + + echo -n "}" +} + +### get luks metadata + +if [ -z "$DEV" ]; then + echo "Did not specify a device!" >&2 + exit 1 +fi + +if [ -z "$SLT" ]; then + echo "Did not specify a slot!" >&2 + exit 1 +fi + +if ! OLD_LUKS_CODED="$(clevis_luks_read_slot "$DEV" "$SLT")"; then + echo "Error reading metadata from LUKS device!" >&2 + exit 1 +fi + +### ---------------------------------------------------------------------- + +DECODED="$(decode_luks_header "$OLD_LUKS_CODED")" + +if ! PIN="$(jose fmt -j- -g clevis -g pin -u- <<< "$DECODED")" || [ -z "$PIN" ]; then + echo "Pin wasn't found in LUKS metadata!" >&2 + exit 1 +fi + +CFG="$(generate_cfg "$OLD_LUKS_CODED")" + +### ---------------------------------------------------------------------- + +echo "Regenerating with:" +echo "PIN: $PIN" +echo "CONFIG: $CFG" + +trap 'echo "Ignoring CONTROL-C!"' INT TERM + +# Get the existing key. +read -r -s -p "Enter existing LUKS password: " existing_key; echo + +# Check if the key is valid. +if ! cryptsetup luksOpen --test-passphrase "${DEV}" <<< "${existing_key}"; then + exit 1 +fi + +if ! clevis luks unbind -d "${DEV}" -s "${SLT}" -f; then + echo "Error during unbind of rotated key from slot:$SLT in $DEV" >&2 + exit 1 +fi + +if ! clevis luks bind -d "${DEV}" -s "${SLT}" "${PIN}" "${CFG}" -k - <<< "${existing_key}"; then + echo "Error during bind of new key from slot:$SLT in $DEV" >&2 + exit 1 +fi + +echo "Keys were succesfully rotated." diff --git a/src/luks/clevis-luks-regen.1.adoc b/src/luks/clevis-luks-regen.1.adoc new file mode 100644 index 0000000..3cd6b7c --- /dev/null +++ b/src/luks/clevis-luks-regen.1.adoc @@ -0,0 +1,36 @@ +CLEVIS-LUKS-REGEN(1) +===================== +:doctype: manpage + + +== NAME + +clevis-luks-regen - Regenerates LUKS metadata + +== SYNOPSIS + +*clevis luks regen* -d DEV -s SLT + +== OVERVIEW + +The *clevis luks regen* command regenerates the LUKS metadata for a given slot in a LUKS device. It effectively +performs an operation equivalent to *clevis luks unbind* and *clevis luks bind* for rebinding said slot and device. + +== OPTIONS + +* *-d* _DEV_ : + The bound LUKS device + +* *-s* _SLT_ : + The slot or key slot number for rebinding. Note that it requires that such slot is currently bound by clevis. + +== EXAMPLE + + Regenerate the binding of slot 1 from /dev/sda1: + + # clevis luks regen -d /dev/sda1 -s 1 + +== SEE ALSO + +link:clevis-luks-bind.1.adoc[*clevis-luks-bind*(1)] +link:clevis-luks-unbind.1.adoc[*clevis-luks-unbind*(1)] diff --git a/src/luks/clevis-luks-report b/src/luks/clevis-luks-report new file mode 100755 index 0000000..f047256 --- /dev/null +++ b/src/luks/clevis-luks-report @@ -0,0 +1,95 @@ +#!/usr/bin/bash -e +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2018 Red Hat, Inc. +# Author: Radovan Sroka +# +# 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 . +# + +. clevis-luks-common-functions + +SUMMARY="Report any key rotation on the server side" + +if [ "$1" == "--summary" ]; then + echo "$SUMMARY" + exit 0 +fi + +function usage_and_exit () { + echo >&2 + echo "Usage: clevis luks report [-qr] -d DEV -s SLOT" >&2 + echo >&2 + echo -e " -q\t Quiet mode" >&2 + echo -e " -r\t Regenerate luks metadata with \"clevis luks regen -d DEV -s SLOT\"" >&2 + echo >&2 + echo "$SUMMARY" >&2 + echo >&2 + exit "$1" +} + +while getopts "hd:s:rq" o; do + case "$o" in + d) DEV="$OPTARG";; + h) usage_and_exit 0;; + r) ROPT="regen";; + s) SLT="$OPTARG";; + q) QOPT="quiet";; + *) usage_and_exit 1;; + esac +done + +### get luks metadata + +if [ -z "$DEV" ]; then + echo "Did not specify a device!" >&2 + exit 1 +fi + +if [ -z "$SLT" ]; then + echo "Did not specify a slot!" >&2 + exit 1 +fi + +if ! DATA_CODED=$(clevis_luks_read_slot "${DEV}" "${SLT}"); then + # Error message was already displayed by clevis_luks_read_slot(), + # at this point. + exit 1 +fi + +EXE="$(findexe clevis-luks-report-decode)" +RESULT="$($EXE "${DATA_CODED}")" + +if [ -n "$RESULT" ]; then + echo "$RESULT" + echo "Report detected that some keys were rotated." + if [ -z "$QOPT" ]; then + if [ -z "$ROPT" ]; then + read -r -p "Do you want to regenerate luks metadata with \"clevis luks regen -d $DEV -s $SLT\"? [ynYN] " ans < /dev/tty + [[ "$ans" =~ ^[yY]$ ]] && ROPT="regen" + fi + fi +else + exit 0 +fi + +if [ "$ROPT" = "regen" ]; then + EXE="$(findexe clevis-luks-regen)" + exec "$EXE" -d "$DEV" -s "$SLT" +else + if [ -n "${RESULT}" ]; then + # Keys were rotated. + exit 1 + fi +fi diff --git a/src/luks/clevis-luks-report-compare b/src/luks/clevis-luks-report-compare new file mode 100755 index 0000000..2ba5132 --- /dev/null +++ b/src/luks/clevis-luks-report-compare @@ -0,0 +1,71 @@ +#!/usr/bin/bash -e +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2018 Red Hat, Inc. +# Author: Radovan Sroka +# +# 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 . +# + +SUMMARY="Compare two sets of keys" + +if [ "$1" == "--summary" ]; then + echo "$SUMMARY" + exit 1 +fi + +if [ -z "$1" ]; then + echo "$0 missing the first argument!" + exit 1 +fi + +if [ -z "$2" ]; then + echo "$0 missing the second argument!" + exit 1 +fi + +ADV_KEYS="$1" # keys from advertisement +LUKS_KEYS="$2" # keys from luks metadata + +### iterate over adv keys and make thumbprints +CNT=0 +declare -a ADV_KEYS_ARRAY +while res="$(jose fmt -j- -g keys -g"$CNT" -o- <<< "$ADV_KEYS")"; do + thp="$(echo "$res" | jose jwk thp -i-)" + ADV_KEYS_ARRAY["$CNT"]="$thp" + CNT=$(( CNT + 1 )) +done + +CNT=0 +while key="$(jose fmt -j- -g keys -g"$CNT" -o- <<< "$LUKS_KEYS")"; do + thp="$(echo "$key" | jose jwk thp -i-)" + + FOUND=0 + for k in "${ADV_KEYS_ARRAY[@]}" + do + if [ "$k" = "$thp" ]; then + FOUND=1 + break + fi + done + + if [ "$FOUND" -eq "0" ]; then + echo "Key \"$thp\" is not in the advertisement and was probably rotated!" + echo "$key" + echo + fi + CNT=$(( CNT + 1 )) +done + +exit 0 diff --git a/src/luks/clevis-luks-report-decode b/src/luks/clevis-luks-report-decode new file mode 100755 index 0000000..f39d1e9 --- /dev/null +++ b/src/luks/clevis-luks-report-decode @@ -0,0 +1,59 @@ +#!/usr/bin/bash -e +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2018 Red Hat, Inc. +# Author: Radovan Sroka +# +# 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 . +# + +. clevis-luks-common-functions + +SUMMARY="Decode luks header" + +if [ "$1" == "--summary" ]; then + echo "$SUMMARY" + exit 1 +fi + +if [ -z "$1" ]; then + echo "$0 missing the first argument!" + exit 1 +fi + +DATA_CODED="$1" + +if DATA_CODED="$(jose jwe fmt -i- <<< "$DATA_CODED")"; then + DATA_CODED="$(jose fmt -j- -g protected -u- <<< "$DATA_CODED")" + DATA_DECODED="$(jose b64 dec -i- <<< "$DATA_CODED")" +else + echo "Error decoding JWE protected header!" >&2 + exit 1 +fi + +### get pin and url + +if ! PIN="$(jose fmt -j- -g clevis -g pin -u- <<< "$DATA_DECODED")" || [ -z "$PIN" ]; then + echo "Pin wasn't found in luks metadata!" >&2 + exit 1 +fi + +if ! CONTENT="$(jose fmt -j- -g clevis -g "$PIN" -o- <<< "$DATA_DECODED")" || [ -z "$CONTENT" ]; then + echo "Content wasn't found!" >&2 + exit 1 +fi + +EXE="$(findexe clevis-luks-report-"$PIN")" + +exec "$EXE" "$CONTENT" diff --git a/src/luks/clevis-luks-report-sss b/src/luks/clevis-luks-report-sss new file mode 100755 index 0000000..1dba4c1 --- /dev/null +++ b/src/luks/clevis-luks-report-sss @@ -0,0 +1,53 @@ +#!/bin/bash -e +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2018 Red Hat, Inc. +# Author: Radovan Sroka +# +# 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 . +# + +. clevis-luks-common-functions + +SUMMARY="SSS report plugin" + +if [ "$1" == "--summary" ]; then + echo "$SUMMARY" + exit 1 +fi + +if [ -z "$1" ]; then + echo "$0 missing the first argument!" >&2 + exit 1 +fi + +CONTENT="$1" # sss content + +CNT=0 +while DATA_CODED="$(jose fmt -j- -g jwe -g"$CNT" -u- <<< "$CONTENT")"; do + if [ -z "$DATA_CODED" ]; then + CNT=$(( CNT + 1 )) + continue # in some cases it can be empty string + fi + + EXE="$(findexe clevis-luks-report-decode)" + if ! $EXE "$DATA_CODED"; then + echo "Failed" >&2 + exit 1 + fi + + CNT=$(( CNT + 1 )) +done + +exit 0 diff --git a/src/luks/clevis-luks-report-tang b/src/luks/clevis-luks-report-tang new file mode 100755 index 0000000..07f2a72 --- /dev/null +++ b/src/luks/clevis-luks-report-tang @@ -0,0 +1,67 @@ +#!/usr/bin/bash -e +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2018 Red Hat, Inc. +# Author: Radovan Sroka +# +# 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 . +# + +. clevis-luks-common-functions + +SUMMARY="Tang report plugin" + +if [ "$1" == "--summary" ]; then + echo "$SUMMARY" + exit 1 +fi + +if [ -z "$1" ]; then + echo "$0 missing the first argument!" + exit 1 +fi + +CONTENT="$1" + +### Get the advertisement +if ! URL="$(jose fmt -j- -g url -u- <<< "$CONTENT")" || [ -z "$URL" ]; then + echo "URL was not found!" >&2 + exit 1 +fi + +if ! jws="$(curl -sfg "$URL/adv")"; then + echo "Unable to fetch advertisement: $URL/adv!" >&2 + exit 1 +fi + +if ! TANG_KEYS="$(jose fmt -j- -Og payload -SyOg keys -AUo- <<< "$jws")"; then + echo "Advertisement is malformed!" >&2 + exit 1 +fi + +### Check advertisement validity +ver="$(jose jwk use -i- -r -u verify -o- <<< "$TANG_KEYS")" +if ! jose jws ver -i "$jws" -k- -a <<< "$ver"; then + echo "Advertisement is missing signatures!" >&2 + exit 1 +fi + +if ! LUKS_KEYS="$(jose fmt -j- -g adv -o- <<< "$CONTENT")" || [ -z "$LUKS_KEYS" ]; then + echo "LUKS keys from LUKS metadata were not found!" >&2 + exit 1 +fi + +EXE="$(findexe clevis-luks-report-compare)" + +exec "$EXE" "$TANG_KEYS" "$LUKS_KEYS" diff --git a/src/luks/clevis-luks-report.1.adoc b/src/luks/clevis-luks-report.1.adoc new file mode 100644 index 0000000..cf42afe --- /dev/null +++ b/src/luks/clevis-luks-report.1.adoc @@ -0,0 +1,41 @@ +CLEVIS-LUKS-REPORT(1) +===================== +:doctype: manpage + + +== NAME + +clevis-luks-report - Reports whether a pin bound to a LUKS1 or LUKS2 volume has been rotated + +== SYNOPSIS + +*clevis luks report* -d DEV -s SLT + +== OVERVIEW + +The *clevis luks report* command checks a given slot of a LUKS device and reports whether the pin bound to it +-- if any -- has been rotated. + +== OPTIONS + +* *-d* _DEV_ : + The bound LUKS device + +* *-s* _SLT_ : + The slot or key slot number for the pin to be verified + +* *-q* : + Quiet mode. If used, we will not prompt whether to regenerate data with *clevis luks regen* + +* *-r* : + Regenerates LUKS metadata with *clevis luks regen -d DEV -s SLOT* + +== EXAMPLE + + Check whether the pin bound to slot 1 in /dev/sda1 has been rotated: + + # clevis luks report -d /dev/sda1 -s 1 + +== SEE ALSO + +link:clevis-luks-regen.1.adoc[*clevis-luks-regen*(1)] diff --git a/src/luks/meson.build b/src/luks/meson.build index 1f64ab0..7c045c4 100644 --- a/src/luks/meson.build +++ b/src/luks/meson.build @@ -15,6 +15,18 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found() bins += join_paths(meson.current_source_dir(), 'clevis-luks-bind') mans += join_paths(meson.current_source_dir(), 'clevis-luks-bind.1') + bins += join_paths(meson.current_source_dir(), 'clevis-luks-common-functions') + + bins += join_paths(meson.current_source_dir(), 'clevis-luks-regen') + mans += join_paths(meson.current_source_dir(), 'clevis-luks-regen.1') + + bins += join_paths(meson.current_source_dir(), 'clevis-luks-report') + bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-compare') + bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-decode') + bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-sss') + bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-tang') + mans += join_paths(meson.current_source_dir(), 'clevis-luks-report.1') + mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlockers.7') else warning('Will not install LUKS support due to missing dependencies!') -- 2.21.0