cryptenroll-varlink: Allow handing in a recovery key
In some cases we want users to copy the recovery key to a save location before we enroll it, therefore allow clients to hand in a recovery key. The next commit will add a varlink method to generate the recovery key. Closes: https://github.com/systemd/systemd/issues/43676
This commit is contained in:
committed by
Luca Boccassi
parent
1c168322cf
commit
c753849fd6
@@ -29,9 +29,15 @@ int enroll_recovery(
|
||||
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = make_recovery_key(&password);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate recovery key: %m");
|
||||
if (c->recovery_key) {
|
||||
password = memdup_suffix0(c->recovery_key, c->recovery_key_size);
|
||||
if (!password)
|
||||
return log_oom();
|
||||
} else {
|
||||
r = make_recovery_key(&password);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate recovery key: %m");
|
||||
}
|
||||
|
||||
r = cryptsetup_set_minimal_pbkdf(cd);
|
||||
if (r < 0)
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef struct MethodEnrollParameters {
|
||||
char *unlock_fido2_device;
|
||||
char *unlock_tpm2_device;
|
||||
char *password;
|
||||
char *recovery_key;
|
||||
char *fido2_device;
|
||||
char *fido2_pin;
|
||||
int fido2_with_client_pin;
|
||||
@@ -65,6 +66,7 @@ static void method_enroll_parameters_done(MethodEnrollParameters *p) {
|
||||
free(p->unlock_fido2_device);
|
||||
free(p->unlock_tpm2_device);
|
||||
erase_and_free(p->password);
|
||||
erase_and_free(p->recovery_key);
|
||||
free(p->fido2_device);
|
||||
erase_and_free(p->fido2_pin);
|
||||
sd_json_variant_unref(p->wipe_slots);
|
||||
@@ -163,6 +165,7 @@ static int vl_method_enroll(
|
||||
{ "unlockFido2Device", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MethodEnrollParameters, unlock_fido2_device), SD_JSON_NULLABLE },
|
||||
{ "unlockTpm2Device", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MethodEnrollParameters, unlock_tpm2_device), SD_JSON_NULLABLE },
|
||||
{ "password", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MethodEnrollParameters, password), SD_JSON_NULLABLE },
|
||||
{ "recoveryKey", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MethodEnrollParameters, recovery_key), SD_JSON_NULLABLE },
|
||||
{ "fido2Device", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MethodEnrollParameters, fido2_device), SD_JSON_NULLABLE },
|
||||
{ "fido2Pin", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MethodEnrollParameters, fido2_pin), SD_JSON_NULLABLE },
|
||||
{ "fido2WithClientPin", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MethodEnrollParameters, fido2_with_client_pin), SD_JSON_NULLABLE },
|
||||
@@ -288,6 +291,20 @@ static int vl_method_enroll(
|
||||
break;
|
||||
|
||||
case ENROLL_RECOVERY:
|
||||
if (p.recovery_key) {
|
||||
_cleanup_(erase_and_freep) char *mangled = NULL;
|
||||
|
||||
r = normalize_recovery_key(p.recovery_key, &mangled);
|
||||
if (r == -EINVAL) /* Not properly formatted, rejecting */
|
||||
return sd_varlink_error_invalid_parameter_name(link, "recoveryKey");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to normalize recovery key: %m");
|
||||
if (!streq(p.recovery_key, mangled))
|
||||
return sd_varlink_error_invalid_parameter_name(link, "recoveryKey");
|
||||
|
||||
c.recovery_key = TAKE_PTR(p.recovery_key);
|
||||
c.recovery_key_size = strlen(c.recovery_key);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENROLL_FIDO2:
|
||||
|
||||
@@ -176,6 +176,7 @@ void enroll_context_done(EnrollContext *c) {
|
||||
c->unlock_tpm2_device = mfree(c->unlock_tpm2_device);
|
||||
c->unlock_password = erase_and_free(c->unlock_password);
|
||||
c->passphrase = erase_and_free(c->passphrase);
|
||||
c->recovery_key = erase_and_free(c->recovery_key);
|
||||
c->fido2_device = mfree(c->fido2_device);
|
||||
c->fido2_salt_file = mfree(c->fido2_salt_file);
|
||||
c->fido2_pin = erase_and_free(c->fido2_pin);
|
||||
|
||||
@@ -66,6 +66,11 @@ typedef struct EnrollContext {
|
||||
char *passphrase;
|
||||
size_t passphrase_size;
|
||||
|
||||
/* New recovery key to enroll (mechanism == recovery). When NULL the helpers fall back to
|
||||
* generate a new recovery key. */
|
||||
char *recovery_key;
|
||||
size_t recovery_key_size;
|
||||
|
||||
/* FIDO2 */
|
||||
char *fido2_device;
|
||||
char *fido2_salt_file;
|
||||
|
||||
@@ -42,6 +42,8 @@ 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_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."),
|
||||
SD_VARLINK_DEFINE_INPUT(fido2Device, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
@@ -65,7 +67,7 @@ static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
SD_VARLINK_DEFINE_OUTPUT(slot, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The keyslots wiped as part of this call, if any."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(wipedSlots, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The generated recovery key, when mechanism is 'recoveryKey'. Contains key material."),
|
||||
SD_VARLINK_FIELD_COMMENT("The generated recovery key or the provided recovery key, when mechanism is 'recovery'. Contains key material."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(recoveryKey, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Progress indicator, only sent on intermediate replies when 'more' was set. Currently the only value is 'touch', signalling that the FIDO2 token is waiting for a touch. Unset on the terminating reply."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(state, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
Reference in New Issue
Block a user