cryptenroll-varlink: Add method to generate a recovery-key

We want users to use a recovery-key generated by systemd. Therefore
expose a method that let's clients generate a key that can be given to
the Enroll method. This way the key can be displayed before enrolling
it.
This commit is contained in:
Julian Sparber
2026-09-23 09:30:28 +02:00
committed by Luca Boccassi
parent c753849fd6
commit 9569d72182
2 changed files with 42 additions and 3 deletions
+34 -2
View File
@@ -15,6 +15,7 @@
#include "json-util.h"
#include "libfido2-util.h"
#include "path-util.h"
#include "recovery-key.h"
#include "string-util.h"
#include "varlink-io.systemd.CryptEnroll.h"
#include "varlink-util.h"
@@ -467,6 +468,36 @@ static int vl_method_list_slots(
return sd_varlink_reply(link, NULL);
}
static int vl_method_make_recovery_key(
sd_varlink *link,
sd_json_variant *parameters,
sd_varlink_method_flags_t flags,
void *userdata) {
_cleanup_(erase_and_freep) char *recovery_key = NULL;
_cleanup_(sd_json_variant_unrefp) sd_json_variant *rk = NULL;
int r;
assert(link);
assert(parameters);
r = sd_varlink_dispatch(link, parameters, /* dispatch_table= */ NULL, /* userdata= */ NULL);
if (r != 0)
return r;
r = make_recovery_key(&recovery_key);
if (r < 0)
return r;
r = sd_json_variant_new_string(&rk, recovery_key);
if (r < 0)
return r;
sd_json_variant_sensitive(rk);
return sd_varlink_replybo(link, SD_JSON_BUILD_PAIR_VARIANT("recoveryKey", rk));
}
int cryptenroll_varlink_server(void) {
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
_cleanup_hashmap_free_ Hashmap *polkit_registry = NULL;
@@ -485,8 +516,9 @@ int cryptenroll_varlink_server(void) {
r = sd_varlink_server_bind_method_many(
varlink_server,
"io.systemd.CryptEnroll.Enroll", vl_method_enroll,
"io.systemd.CryptEnroll.ListSlots", vl_method_list_slots);
"io.systemd.CryptEnroll.Enroll", vl_method_enroll,
"io.systemd.CryptEnroll.ListSlots", vl_method_list_slots,
"io.systemd.CryptEnroll.MakeRecoveryKey", vl_method_make_recovery_key);
if (r < 0)
return log_error_errno(r, "Failed to bind Varlink methods: %m");
+8 -1
View File
@@ -42,7 +42,7 @@ static SD_VARLINK_DEFINE_METHOD_FULL(
SD_VARLINK_FIELD_COMMENT("The passphrase to enroll, when mechanism is 'password'. Contains key material."),
SD_VARLINK_DEFINE_INPUT(password, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("A recovery key to enroll, when mechanism is 'recovery'. The key must be in the normalized form and have high entropy. Contains key material."),
SD_VARLINK_FIELD_COMMENT("A recovery key to enroll, when mechanism is 'recovery'. The key must be in the normalized form and have high entropy. Use MakeRecoveryKey() to generate the recovery key. Contains key material."),
SD_VARLINK_DEFINE_INPUT(recoveryKey, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Path to the FIDO2 device to enroll, when mechanism is 'fido2'. Leave empty to automatically discover a suitable device."),
@@ -82,6 +82,11 @@ static SD_VARLINK_DEFINE_METHOD_FULL(
SD_VARLINK_FIELD_COMMENT("The type of the keyslot."),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(type, EnrollMechanism, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_METHOD(
MakeRecoveryKey,
SD_VARLINK_FIELD_COMMENT("The generated recovery key."),
SD_VARLINK_DEFINE_OUTPUT(recoveryKey, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_ERROR(VolumeUnderForeignManagement);
static SD_VARLINK_DEFINE_ERROR(PasswordRequired);
static SD_VARLINK_DEFINE_ERROR(PasswordIncorrect);
@@ -98,6 +103,8 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_method_Enroll,
SD_VARLINK_SYMBOL_COMMENT("Enumerate the keyslots currently enrolled in a LUKS2 volume, one per reply. Must be called with the 'more' flag."),
&vl_method_ListSlots,
SD_VARLINK_SYMBOL_COMMENT("Generate a recovery key that can be enrolled using the 'recovery' mechanism in Enroll()."),
&vl_method_MakeRecoveryKey,
SD_VARLINK_SYMBOL_COMMENT("The volume is managed by another subsystem (e.g. systemd-homed) and may not be enrolled into directly."),
&vl_error_VolumeUnderForeignManagement,
SD_VARLINK_SYMBOL_COMMENT("A password is required to unlock the volume, but none was provided."),