Skip to content

Commit

Permalink
Add PKCS#11 pin basic functionality
Browse files Browse the repository at this point in the history
Signed-off-by: Sergio Arroutbi <[email protected]>
  • Loading branch information
sarroutbi committed Jul 12, 2024
1 parent a4dd9dd commit 8620f43
Show file tree
Hide file tree
Showing 20 changed files with 1,157 additions and 8 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/install-dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ debian:*|ubuntu:*)
while ! apt-get -y install ${COMMON} \
build-essential pkg-config libssl-dev libjansson-dev libjose-dev \
luksmeta libluksmeta-dev libpwquality-tools libglib2.0-dev \
libudisks2-dev libaudit-dev systemd; do
libudisks2-dev libaudit-dev systemd opensc pcscd; do

sleep 5
done
Expand All @@ -48,7 +48,8 @@ debian:*|ubuntu:*)
yum -y --allowerasing install ${COMMON}
yum -y install pkgconfig openssl-devel openssl zlib-devel \
jansson-devel findutils gcc libjose-devel luksmeta libluksmeta-devel \
audit-libs-devel tpm2-tools desktop-file-utils cracklib-dicts
audit-libs-devel tpm2-tools desktop-file-utils cracklib-dicts opensc \
pcsc-lite
sed -i 's|>=1\.0\.2|>=1\.0\.1|' meson.build
;;
esac
Expand Down
29 changes: 24 additions & 5 deletions src/luks/clevis-luks-common-functions.in
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,22 @@ clevis_luks_print_pin_config() {

local pin=
case "${P}" in
pkcs11)
local uri
uri="$(jose fmt -j- -g uri -u- <<< "${content}")"
mechanism="$(jose fmt -j- -g mechanism -u- <<< "${content}")"
if [ -z "${mechanism}" ]; then
pin=$(printf '{"uri":"%s"}' "${uri}")
else
pin=$(printf '{"uri":"%s", "mechanism":"%s"}' "${uri}" "${mechanism}")
fi
printf "pkcs11 '%s'" "${pin}"
;;
sss)
local threshold
threshold=$(jose fmt -j- -Og t -o- <<< "${content}")
clevis_luks_process_sss_pin "${content}" "${threshold}"
;;
tang)
local url
url="$(jose fmt -j- -g url -u- <<< "${content}")"
Expand All @@ -197,11 +213,6 @@ clevis_luks_print_pin_config() {
pin=${pin/#,/}
printf "tpm2 '{%s}'" "${pin}"
;;
sss)
local threshold
threshold=$(jose fmt -j- -Og t -o- <<< "${content}")
clevis_luks_process_sss_pin "${content}" "${threshold}"
;;
*)
printf "unknown pin '%s'" "${P}"
;;
Expand Down Expand Up @@ -241,6 +252,7 @@ clevis_luks_process_sss_pin() {
local jwe="${1}"
local threshold="${2}"

local sss_pkcs11
local sss_tang
local sss_tpm2
local sss
Expand All @@ -255,6 +267,9 @@ clevis_luks_process_sss_pin() {
fi
read -r pin cfg <<< "${pin_cfg}"
case "${pin}" in
pkcs11)
sss_pkcs11="${sss_pkcs11},${cfg}"
;;
tang)
sss_tang="${sss_tang},${cfg}"
;;
Expand All @@ -276,6 +291,10 @@ clevis_luks_process_sss_pin() {
cfg="${cfg},"$(clevis_luks_join_sss_cfg "tpm2" "${sss_tpm2}")
fi

if [ -n "${sss_pkcs11}" ]; then
cfg="${cfg},"$(clevis_luks_join_sss_cfg "pkcs11" "${sss_pkcs11}")
fi

if [ -n "${sss}" ]; then
cfg=$(printf '%s,"sss":%s' "${cfg}" "${sss}")
fi
Expand Down
18 changes: 18 additions & 0 deletions src/luks/dracut/clevis-pin-pkcs11/clevis-pkcs11-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
#
# Copyright (c) 2024 Red Hat, Inc.
#
# 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/>.
#
pcscd --disable-polkit
18 changes: 18 additions & 0 deletions src/luks/dracut/clevis-pin-pkcs11/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
dracut = dependency('dracut', required: false)

if dracut.found()
dracutdir = dracut.get_pkgconfig_variable('dracutmodulesdir') + '/60' + meson.project_name() + '-pin-pkcs11'

configure_file(
input: 'module-setup.sh.in',
output: 'module-setup.sh',
install_dir: dracutdir,
configuration: data,
)

# TODO: install hook for pcscd start
install_data('clevis-pkcs11-hook.sh', install_dir: dracutdir)

else
warning('Will not install dracut module clevis-pin-pkcs11 due to missing dependencies!')
endif
40 changes: 40 additions & 0 deletions src/luks/dracut/clevis-pin-pkcs11/module-setup.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2024 Red Hat, Inc.
#
# 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/>.
#

depends() {
echo clevis
return 255
}

install() {
inst_hook initqueue/online 60 "${moddir}/clevis-pkcs11-hook.sh"

Check warning

Code scanning / shellcheck

moddir is referenced but not assigned. Warning

moddir is referenced but not assigned.
inst_hook initqueue/settled 60 "${moddir}/clevis-pkcs11-hook.sh"

inst_multiple \
pcscd \
/usr/lib64/pcsc/drivers/ifd-ccid.bundle/Contents/Linux/libccid.so \
/usr/lib64/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist \
/usr/lib64/libykcs11.so.2 \
/usr/lib64/opensc-pkcs11.so \
/usr/lib64/pkcs11/opensc-pkcs11.so \
pkcs11-tool \
clevis-decrypt-pkcs11

dracut_need_initqueue
}
1 change: 1 addition & 0 deletions src/luks/dracut/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ subdir('clevis-pin-tang')
subdir('clevis-pin-tpm2')
subdir('clevis-pin-sss')
subdir('clevis-pin-null')
subdir('clevis-pin-pkcs11')
4 changes: 4 additions & 0 deletions src/luks/systemd/clevis-luks-pkcs11-askpass.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
/usr/libexec/clevis-luks-pkcs11-askpin &
# Wait 30 seconds to attend keys. If control socket receives information, this time is cancelled
clevis-pkcs11-afunix-socket-unlock -f /run/systemd/clevis-pkcs11.sock -s 30
8 changes: 8 additions & 0 deletions src/luks/systemd/clevis-luks-pkcs11-askpass.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[Unit]
Description=Unencrypt through PKCS11
DefaultDependencies=no
PartOf=clevis-luks-pkcs11-askpass.socket

[Service]
Type=simple
ExecStart=/usr/libexec/clevis-luks-pkcs11-askpass
13 changes: 13 additions & 0 deletions src/luks/systemd/clevis-luks-pkcs11-askpass.socket
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# clevis pkcs11 socket
[Unit]
Description=Clevis PKCS11 socket handler
Requires=clevis-luks-pkcs11-askpass.service
Wants=cryptsetup-pre.target
After=sockets.target systemd-ask-password-wall.service

[Socket]
ListenDatagram=/run/systemd/clevis-pkcs11.sock

[Install]
RequiredBy=cryptsetup-pre.target
WantedBy=sockets.target systemd-ask-password-wall.service
93 changes: 93 additions & 0 deletions src/luks/systemd/clevis-luks-pkcs11-askpin.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash
. clevis-luks-common-functions
. clevis-pkcs11-common

pkcs11_device=""

get_pkcs11_error() {
if journalctl -u clevis-luks-pkcs11-askpass.service -b 0 | tail -3 \
| egrep -E "A TPM2 device.{1,}needed" >/dev/null 2>&1;
then
echo "ERROR:TPM2 device not found. "
elif journalctl -u clevis-luks-pkcs11-askpass.service -b 0 | tail -3 \
| egrep -E "Error.{1,}server" >/dev/null 2>&1;
then
echo "ERROR:Tang communication error. "
elif journalctl -u clevis-luks-pkcs11-askpass.service -b 0 | tail -3 \
| grep "Invalid PIN" >/dev/null 2>&1;
then
echo "ERROR:Invalid PIN. "
else
echo "ERROR:Unknown error. "
fi
return 0
}

if command -v pcscd; then
echo "clevis-pkcs11: starting pcscd if not available ..."
echo -e "clevis-pkcs11: pcscd running?:[$(ps auxf | grep [p]cscd)]\n"

Check warning

Code scanning / shellcheck

Quote the grep pattern so the shell won't interpret it. Warning

Quote the grep pattern so the shell won't interpret it.
if ! ps auxf | grep "[p]cscd";
then
echo "clevis-pkcs11: starting pcscd ..."
pcscd --disable-polkit
fi
fi

pkcs11-tool -L
if ! pkcs11_device=$(pkcs11-tool -L | grep "Slot" | head -1 | awk -F ":" '{print $2}' | sed -e 's@^ *@@g'); then
echo "No PKCS11 device detected / pkcs11-tool error"
exit 1
fi

while [ -z "${pkcs11_device}" ]; do
option=$(systemd-ask-password --echo "Detected an empty PKCS#11 device, continue PKCS#11 detection? [yY/nN]")
if [ "${option}" == "N" ] || [ "${option}" == "n" ] ; then
echo "Won't continue PKCS11 device detection"
exit 1
fi
pkcs11_device=$(pkcs11-tool -L | grep "Slot" | head -1 | awk -F ":" '{print $2}' | sed -e 's@^ *@@g')
done
echo "Detected PKCS11 device:${pkcs11_device}"

# Let's analyze all entries from /etc/crypttab that contain clevis-pkcs11.sock entries
grep -v "^#" /etc/crypttab | while read -r line;
do
if echo "${line}" | grep -E "clevis-pkcs11.sock" 1>/dev/null;
then
next_device=0
msg=""
while [ ${next_device} -ne 1 ]; do
uuid=$(echo "${line}" | awk '{print $2}')
noUUID=$(echo "${uuid}" | sed -e 's@UUID=@@g')
if ! mapped_device=$(clevis_map_device "${uuid}"); then
echo "Could not check mapped device for UID:${uuid}"
next_device=1
continue
fi
# If no PKCS#11 configuration, advance to next device
if ! clevis luks list -d "${mapped_device}" | grep pkcs11 >/dev/null 2>&1; then
echo "Device:${mapped_device} does not contain PKCS#11 configuration"
next_device=1
continue
fi
# Check if configuration contains a pin
uri=$(clevis luks list -d "${mapped_device}" | awk -F '"uri":' '{print $2}' | awk -F '"' '{print $2}' | awk -F '"' '{print $1}')
if ! pin=$(clevis_get_pin_value_from_uri "${uri}"); then
pin=$(systemd-ask-password "${msg}Please, insert PIN for ${pkcs11_device} (${uuid}):")
fi
# Get key from PKCS11 pin here and feed AF_UNIX socket program
echo "${pin}" > /run/systemd/clevis-pkcs11.pin
if ! passphrase=$(clevis_luks_unlock_device "${mapped_device}") || [ -z "${passphrase}" ]; then
echo "Could not unlock device:${mapped_device}"
msg="$(get_pkcs11_error)"
continue
fi
next_device=1
echo "Device:${mapped_device} unlocked successfully"
echo "${passphrase}" > /run/systemd/clevis-pkcs11."${noUUID}".passphrase
# Send passphrase to control socket
luks_device="luks-${noUUID}"
echo -n "${luks_device},${passphrase}" | socat UNIX-CONNECT:/run/systemd/clevis-pkcs11.control.sock -
done
fi
done
20 changes: 19 additions & 1 deletion src/luks/systemd/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,33 @@ if systemd.found() and sd_reply_pass.found()
install_dir: unitdir,
configuration: data,
)

configure_file(
input: 'clevis-luks-pkcs11-askpass.service.in',
output: 'clevis-luks-pkcs11-askpass.service',
install_dir: unitdir,
configuration: data,
)
configure_file(
input: 'clevis-luks-askpass.in',
output: 'clevis-luks-askpass',
install_dir: libexecdir,
configuration: data
)
configure_file(
input: 'clevis-luks-pkcs11-askpass.in',
output: 'clevis-luks-pkcs11-askpass',
install_dir: libexecdir,
configuration: data
)
configure_file(
input: 'clevis-luks-pkcs11-askpin.in',
output: 'clevis-luks-pkcs11-askpin',
install_dir: libexecdir,
configuration: data
)

install_data('clevis-luks-askpass.path', install_dir: unitdir)
install_data('clevis-luks-pkcs11-askpass.socket', install_dir: unitdir)
else
warning('Will not install systemd support due to missing dependencies!')
endif
1 change: 1 addition & 0 deletions src/pins/meson.build
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
subdir('sss')
subdir('tang')
subdir('tpm2')
subdir('pkcs11')
Loading

0 comments on commit 8620f43

Please sign in to comment.