With 1df4b21abd we started to default to
enrolling into the LUKS device backing the root fs if none was specified
(and no wipe operation is used). This changes to look for /var/ instead.
On most systems /var/ is going to be on the root fs, hence this change
is with little effect.
However, on systems where / and /var/ is separate it makes more sense to
default to /var/ because that's where the persistent and variable data
is placed (i.e. where LUKS should be used) while / doesn't really have
to be variable, could as well be immutable, or ephemeral. Hence /var/
should be a safer default.
Or to say this differently: I think it makes sense to support systems
with /var/ being on / well. I also think it makes sense to support
systems with them being separate, and /var/ being variable and
persistent. But any other kind of system I find much less interesting to
support, and in that case people should just specify the device name.
Also, while we are at it, tighten the checks a bit, insist on a dm-crypt
+ LUKS superblock before continuing.
And finally, let's print a short message indicating the device we
operate on.
We so far just print a short log message that is not very useful, let's
add some recognizable error codes, and output better log messages if we
can't get TPM stuff to work.
Fixes: #31925
This bool controls whether we should interactively ask for a password,
which is pretty much what the ask_password-api.c APIs are about. Hence,
just make the bool a flag in AskPasswordFlags enum, and use it
everywhere.
This still catches the flag early in upper levels of the codebase,
exactly as before, but if the flag is still present in the lower layers
it's also handled there and results in ENOEXEC if seen.
This is mostly an excercise in simplifying our ridiculously long
function call parameter lists a bit.
Let's make sure that when cryptenroll asks for the TPM2 or FIDO2 token
PIN it uses cryptenroll.* credential namespace, and cryptsetup uses
cryptsetup.*.
similar as the previous commit, let's clean up the credential name we
use. Use home.token-pin in case of homectl, and cryptenroll.pkcs11-pin
in case of cryptenroll.
The TPM2 enrollment is the only of the three token enrollments where the
user picks a PIN at enrollment time (the others have a PIN set for the
token, not for the enrollment). Let's make sure it uses a different
credential for retrieving this PIN, in order to make sure people can
programmatically change PINs via credentials (in which case they need to
supply both).
Querying a fido2 PIN via askpw for enrolling is currently used in two
places: cryptenroll and homectl. So far we sloppily used the same fixed
credential name "fido2-pin" in both cases. Let's tweak that and make the
credential name match the other credentials cryptenroll or home query,
i.e. using the cryptenroll.* and home.* namespaces.
This is particular done in light of #31370, which wants to make the
credential name public. We really should get the name in order before
making it public.
The "id" is used in the askpw protocol to recognize password prompts, in
case a service is replying to them and needs some id. Previously we set
an incorrect id, the one of cryptsetup. Fix that.
(I guess the id is not used much, it comes from a time where we had no
credentials, and thus some people wanted to supply passphrases
programmatically rather interactively. The usecase is probably gone, but
we should still set some valid id I guess.)
Rather than adding more and more parameters to ask_password_auto(), let's
pass a structure of the fields that often are constant anyway.
This way, callers can fill in what they need, and we take the filled
structure which we can pass around internally as one.
This is in particular preparation for adding one more field in one of
the next commits.
systemd-cryptenroll uses the READ_FULL_FILE_CONNECT_SOCKET flag when
reading the keyfile to also allow reading it from a socket. But it also
sets the offset to 0, causing an unnecessary seek to the beginning of
the newly opened keyfile and disables socket support again, as these do
not support seeking.
Disable seeking entirely to remove the unneeded seek and restore support
for reading the keyfile from a socket again as with systemd-cryptsetup.
cryptenroll accepts only PKCS#11 URIs that match both a certificate and a private key in a token.
This patch allows users to provide a PKCS#11 URI that points to a certificate only, and makes possible to use output of some PKCS#11 tools directly.
Internally the patch changes 'type=cert' in the provided PKCS#11 URI to 'type=private' before storing in a LUKS2 header.
Fixes: #23479
The tpm2_tpm2b_public_from_pem() invocation only makes sense when we
succeed to load the file from disk, hence we might do this together and
safe a conditionalization.
No change in behaviour, let's just move this over so that we can reuse
this in repart later (and don't have to export the ugly `sym_` function
pointer for it)
Let's define the same switches and their backing variables in the same
order, and let's make sure the enums and switches are named the same.
No actual code changes.
Instead of enrolling the local TPM to a luks volume, use the public key from a
TPM to enroll it into the luks volume. This is useful when enrolling a TPM that
is not currently accessible, for example if the TPM is located on a different
system.
If `--tpm2-public-key=` is not specified, but `tpm2-pcr-public-key.pem` exists
in /{etc,run,usr/lib}/systemd/, the default PCR 11 is not being set.
Fixes 9e437994
Let's switch the order in which we process positional arguments and
analyze/tweak detail parameters. Let's look at the positional arguments
first (i.e. the "big picture") and then look at the switches (i.e.
"little details").
THis doesn't matter much, but makes for better error messages I think.
At least I was very confused that a completely borked cmdline I passed
to cryptenrolled complained about some detail and let the major fuckup
pass...
This removes a duplicate condition check by adding a common surrounding
if block.
This also change a confusing if check: "(X && Y) && Z" to simply "X && Y && Z"
This matches the change to tpm2_seal(), which now accepts a Tpm2Context instead
of a device string.
This also allows using the same TPM context for sealing and unsealing, which
will be required by (future) test code when sealing/unsealing using a transient
key.
Because most TPM2 functions here are 'library-like' functions, they should be
at debug level, not error level.
The only functions not reduced to logging at debug are tpm2_list_devices(),
since it is expected to print output, and the tpm2_parse_pcr_argument_*()
functions, since the system-wide parse_*_argument() functions generally log at
error level.