Skip to content

Commit 08226c6

Browse files
author
Christoph Biedl
committed
Implement a pin to store the key in a single file
This is a very simple pin, and possibly rather for educational purposes: Store the jwk at a given place in the file system.
1 parent 22cb93d commit 08226c6

File tree

8 files changed

+306
-0
lines changed

8 files changed

+306
-0
lines changed

src/pins/file/clevis-decrypt-file

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
3+
set -eu
4+
5+
# Copyright (c) 2020 Christoph Biedl
6+
# Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
7+
#
8+
# This program is free software: you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 3 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# This program is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
#
21+
22+
[ $# -eq 1 ] && [ "${1:-}" = "--summary" ] && exit 2
23+
24+
if [ -t 0 ] ; then
25+
echo >&2
26+
echo 'Usage: clevis decrypt file < JWE > PLAINTEXT' >&2
27+
echo >&2
28+
exit 1
29+
fi
30+
31+
read -d . hdr64
32+
if ! hdr="$(jose fmt --quote="$hdr64" --string --b64load --object --output=-)" ; then
33+
echo 'JWE header corrupt' >&2
34+
exit 1
35+
fi
36+
37+
if [ "$(jose fmt --json="$hdr" --get clevis --get pin --unquote=-)" != 'file' ] ; then
38+
echo 'JWE pin mismatch!' >&2
39+
exit 1
40+
fi
41+
42+
if ! name="$(jose fmt --json="$hdr" --get clevis --get file --get name --unquote=-)" ; then
43+
echo 'JWE missing 'clevis.file.name' header parameter!' >&2
44+
exit 1
45+
fi
46+
47+
if [ ! -f "$name" ] ; then
48+
echo "Key file $name not found" >&2
49+
exit 1
50+
fi
51+
52+
jwk="$(cat "$name")"
53+
54+
if ! jose fmt --json="$jwk" --object --output=/dev/null 2>/dev/null ; then
55+
echo "Key file $name is malformed" >&2
56+
exit 1
57+
fi
58+
59+
( printf '%s' "$jwk$hdr64." ; cat ) | exec jose jwe dec --key=- --input=-

src/pins/file/clevis-encrypt-file

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
5+
# Copyright (c) 2020 Christoph Biedl
6+
# Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
7+
#
8+
# This program is free software: you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 3 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# This program is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
#
21+
22+
SUMMARY='Encrypts using a jwk stored in a file policy'
23+
24+
if [ "${1:-}" = '--summary' ] ; then
25+
echo "$SUMMARY"
26+
exit 0
27+
fi
28+
29+
if [ -t 0 ] ; then
30+
exec >&2
31+
echo
32+
echo 'Usage: clevis encrypt file CONFIG < PLAINTEXT > JWE'
33+
echo
34+
echo "$SUMMARY"
35+
echo
36+
echo 'his command uses the following configuration properties:'
37+
echo
38+
echo ' name: <string> The file that holds the encryption key (REQUIRED)'
39+
echo
40+
exit 2
41+
fi
42+
43+
if ! cfg="$(jose fmt --json="$1" --object --output=- 2>/dev/null)" ; then
44+
echo 'Configuration is malformed!' >&2
45+
exit 1
46+
fi
47+
48+
if ! name="$(jose fmt --json="$cfg" --object --get name --unquote=-)" ; then
49+
echo 'Missing the required name property!' >&2
50+
exit 1
51+
fi
52+
53+
if [ -e "$name" ] ; then
54+
echo "File $name already exists" >&2
55+
exit 1
56+
fi
57+
58+
jwk="$(jose jwk gen --input='{"alg":"A256GCM"}')"
59+
60+
( umask 0377 ; echo "$jwk" >"$name" )
61+
62+
jwe='{"protected":{"clevis":{"pin":"file","file":{}}}}'
63+
jwe="$(jose fmt --json="$jwe" --get protected --get clevis --get file --quote "$name" --set name -UUUU --output=-)"
64+
65+
( printf '%s' "$jwe$jwk" ; cat ) | exec jose jwe enc --input=- --key=- --detached=- --compact
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
CLEVIS-ENCRYPT-FILE(1)
2+
======================
3+
:doctype: manpage
4+
5+
6+
== NAME
7+
8+
clevis-encrypt-file - Encrypts using a file policy
9+
10+
== SYNOPSIS
11+
12+
*clevis encrypt file* CONFIG < PT > JWE
13+
14+
== OVERVIEW
15+
16+
The *clevis encrypt file* command encrypts using a file policy.
17+
Its only argument is the JSON configuration object.
18+
19+
Encrypting data using the file pin works like this:
20+
21+
$ clevis encrypt file '{"name":"/path/to/file"}' < PT > JWE
22+
23+
The given file must not exist yet.
24+
25+
To decrypt the data, just pass it to the *clevis decrypt* command:
26+
27+
$ clevis decrypt < JWE > PT
28+
29+
== CONFIG
30+
31+
This command uses the following configuration properties:
32+
33+
* *name* (string) :
34+
The name to the file where the jwk is stored (REQUIRED)
35+
36+
== BUGS
37+
38+
Requires the directories for that file already exists.
39+
40+
Rather for educational purposes.
41+
42+
== SEE ALSO
43+
44+
link:clevis-decrypt.1.adoc[*clevis-decrypt*(1)]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2020 Christoph Biedl
4+
# Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
#
19+
20+
depends() {
21+
echo clevis
22+
return 0
23+
}
24+
25+
install() {
26+
inst clevis-decrypt-file
27+
}

src/pins/file/initramfs.in

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2020 Christoph Biedl
4+
# Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
#
19+
20+
case $1 in
21+
prereqs)
22+
exit 0
23+
;;
24+
esac
25+
26+
. @initramfstoolsdir@/hook-functions
27+
28+
die() {
29+
code="$1"
30+
msg="$2"
31+
echo " (ERROR): $msg" >&2
32+
exit $1
33+
}
34+
35+
copy_exec @bindir@/clevis-decrypt-file || die 1 "@bindir@/clevis-decrypt-file not found"

src/pins/file/meson.build

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
dracut = dependency('dracut', required: false)
3+
initramfs_tools = find_program('update-initramfs', required: false)
4+
5+
bins += join_paths(meson.current_source_dir(), 'clevis-decrypt-file')
6+
bins += join_paths(meson.current_source_dir(), 'clevis-encrypt-file')
7+
mans += join_paths(meson.current_source_dir(), 'clevis-encrypt-file.1')
8+
9+
env = environment()
10+
env.append('PATH',
11+
join_paths(meson.source_root(), 'src'),
12+
meson.current_source_dir(),
13+
'/usr/libexec',
14+
libexecdir,
15+
separator: ':'
16+
)
17+
18+
test('pin-file', find_program('./pin-file'), env: env)
19+
20+
if dracut.found()
21+
dracutdir = dracut.get_pkgconfig_variable('dracutmodulesdir') + '/60' + meson.project_name() + '-pin-file'
22+
configure_file(
23+
input: 'dracut.module-setup.sh.in',
24+
output: 'module-setup.sh',
25+
install_dir: dracutdir,
26+
configuration: data,
27+
)
28+
else
29+
warning('Will not install dracut module clevis-pin-file due to missing dependencies!')
30+
endif
31+
32+
if initramfs_tools.found()
33+
initramfstools_dir = '/usr/share/initramfs-tools'
34+
initramfs_hooks_dir = '/usr/share/initramfs-tools/hooks'
35+
initramfs_data = configuration_data()
36+
initramfs_data.merge_from(data)
37+
initramfs_data.set('initramfstoolsdir', initramfstools_dir)
38+
configure_file(
39+
input: 'initramfs.in',
40+
output: 'clevis-pin-file',
41+
install_dir: initramfs_hooks_dir,
42+
configuration: initramfs_data,
43+
)
44+
else
45+
warning('Will not install initramfs module clevis-pin-file due to missing dependencies!')
46+
endif

src/pins/file/pin-file

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/sh
2+
3+
set -ex
4+
5+
# Copyright (c) 2020 Christoph Biedl
6+
# Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
7+
#
8+
# This program is free software: you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 3 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# This program is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
#
21+
22+
TMP="$(mktemp -d)"
23+
trap "rm -rf \"$TMP\"" EXIT
24+
25+
cfg="$(printf '{"name":"%s"}' "$TMP/key")"
26+
inp='hi'
27+
enc="$(printf '%s' "$inp" | clevis encrypt file "$cfg")"
28+
dec="$(printf '%s' "$enc" | clevis decrypt)"
29+
test "$dec" = "$inp"

src/pins/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
subdir('file')
12
subdir('sss')
23
subdir('tang')
34
subdir('tpm2')

0 commit comments

Comments
 (0)